feat:添加Redis缓存服务
- 实现Redis服务接口和抽象层 - 提供真实Redis服务实现 (RealRedisService) - 提供文件模拟Redis服务 (FileRedisService) 用于开发测试 - 支持基本的Redis操作:get、set、del、exists、ttl - 添加Redis模块配置和依赖注入
This commit is contained in:
127
src/core/redis/real-redis.service.ts
Normal file
127
src/core/redis/real-redis.service.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { Injectable, Logger, OnModuleDestroy } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import Redis from 'ioredis';
|
||||
import { IRedisService } from './redis.interface';
|
||||
|
||||
/**
|
||||
* 真实Redis服务
|
||||
* 连接到真实的Redis服务器
|
||||
*/
|
||||
@Injectable()
|
||||
export class RealRedisService implements IRedisService, OnModuleDestroy {
|
||||
private readonly logger = new Logger(RealRedisService.name);
|
||||
private redis: Redis;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.initializeRedis();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Redis连接
|
||||
*/
|
||||
private initializeRedis(): void {
|
||||
const redisConfig = {
|
||||
host: this.configService.get<string>('REDIS_HOST', 'localhost'),
|
||||
port: this.configService.get<number>('REDIS_PORT', 6379),
|
||||
password: this.configService.get<string>('REDIS_PASSWORD') || undefined,
|
||||
db: this.configService.get<number>('REDIS_DB', 0),
|
||||
retryDelayOnFailover: 100,
|
||||
maxRetriesPerRequest: 3,
|
||||
lazyConnect: true,
|
||||
};
|
||||
|
||||
this.redis = new Redis(redisConfig);
|
||||
|
||||
this.redis.on('connect', () => {
|
||||
this.logger.log('Redis连接成功');
|
||||
});
|
||||
|
||||
this.redis.on('error', (error) => {
|
||||
this.logger.error('Redis连接错误', error);
|
||||
});
|
||||
|
||||
this.redis.on('close', () => {
|
||||
this.logger.warn('Redis连接关闭');
|
||||
});
|
||||
}
|
||||
|
||||
async set(key: string, value: string, ttl?: number): Promise<void> {
|
||||
try {
|
||||
if (ttl && ttl > 0) {
|
||||
await this.redis.setex(key, ttl, value);
|
||||
} else {
|
||||
await this.redis.set(key, value);
|
||||
}
|
||||
this.logger.debug(`设置Redis键: ${key}, TTL: ${ttl || '永不过期'}`);
|
||||
} catch (error) {
|
||||
this.logger.error(`设置Redis键失败: ${key}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async get(key: string): Promise<string | null> {
|
||||
try {
|
||||
return await this.redis.get(key);
|
||||
} catch (error) {
|
||||
this.logger.error(`获取Redis键失败: ${key}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async del(key: string): Promise<boolean> {
|
||||
try {
|
||||
const result = await this.redis.del(key);
|
||||
this.logger.debug(`删除Redis键: ${key}, 结果: ${result > 0}`);
|
||||
return result > 0;
|
||||
} catch (error) {
|
||||
this.logger.error(`删除Redis键失败: ${key}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async exists(key: string): Promise<boolean> {
|
||||
try {
|
||||
const result = await this.redis.exists(key);
|
||||
return result > 0;
|
||||
} catch (error) {
|
||||
this.logger.error(`检查Redis键存在性失败: ${key}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async expire(key: string, ttl: number): Promise<void> {
|
||||
try {
|
||||
await this.redis.expire(key, ttl);
|
||||
this.logger.debug(`设置Redis键过期时间: ${key}, TTL: ${ttl}秒`);
|
||||
} catch (error) {
|
||||
this.logger.error(`设置Redis键过期时间失败: ${key}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async ttl(key: string): Promise<number> {
|
||||
try {
|
||||
return await this.redis.ttl(key);
|
||||
} catch (error) {
|
||||
this.logger.error(`获取Redis键TTL失败: ${key}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async flushall(): Promise<void> {
|
||||
try {
|
||||
await this.redis.flushall();
|
||||
this.logger.log('清空所有Redis数据');
|
||||
} catch (error) {
|
||||
this.logger.error('清空Redis数据失败', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
onModuleDestroy(): void {
|
||||
if (this.redis) {
|
||||
this.redis.disconnect();
|
||||
this.logger.log('Redis连接已断开');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user