跳转到内容

缓存模块

基于 ioredis 的高性能缓存服务,内置生命周期管理、健康检查、自动重连。

模块注册

typescript
import { CacheModule } from '@maxtan/nest-core'

@Module({
  imports: [
    CacheModule.forRoot(
      {
        host: 'localhost',
        port: 6379,
        password: 'your-password',
        db: 0
      },
      true // 是否全局注册,默认 true
    )
  ]
})
export class AppModule {}

配置选项

支持简写(直接传 RedisOptions)和扩展两种格式:

typescript
// 简写:直接传 ioredis 连接配置
CacheModule.forRoot({ host: 'localhost', port: 6379 })

// 扩展:附加模块级选项
CacheModule.forRoot({
  redis: { host: 'localhost', port: 6379 },
  strict: true   // 严格模式
})
选项类型默认值说明
redisRedisOptionsioredis 连接配置
strictbooleanfalse严格模式:Redis 断连时操作抛出异常;关闭时抛出 CacheNotReadyException 可 try/catch 降级

基础用法

typescript
import { Injectable } from '@nestjs/common'
import { CacheService } from '@maxtan/nest-core'

@Injectable()
export class YourService {
  constructor(private readonly cacheService: CacheService) {}

  async getData(key: string) {
    // 获取缓存
    const cached = await this.cacheService.get(key)
    if (cached) return cached

    // 设置缓存(TTL 秒)
    const data = await this.fetchData()
    await this.cacheService.set(key, JSON.stringify(data), 3600)
    return data
  }
}

对象序列化

自动 JSON 序列化 / 反序列化:

typescript
// 设置对象
await this.cacheService.setObject(key, { name: 'John', age: 25 }, 3600)

// 获取对象(自动 JSON.parse)
const user = await this.cacheService.getObject<UserData>(key)

批量操作

typescript
// 批量获取
const values = await this.cacheService.mget('key1', 'key2', 'key3')

// 批量设置
await this.cacheService.mset({ key1: 'value1', key2: 'value2' })

计数器

typescript
const count = await this.cacheService.incr('counter:visits')

健康检查

typescript
const isReady = await this.cacheService.isReady()
return { redis: isReady ? 'healthy' : 'unhealthy' }

完整 API

键值操作

方法签名说明
get(key) → string | null获取字符串值
set(key, value, ttl?) → 'OK'设置值(可选 TTL 秒)
setNX(key, value, ttl?) → 'OK' | null不存在时设置(分布式锁常用)
setXX(key, value, ttl?) → 'OK' | null存在时才更新
del(...keys) → number删除键,返回删除数量
exists(key) → number判断键是否存在(1/0)
ttl(key) → number获取剩余 TTL(-2 不存在,-1 永久)
expire(key, ttl) → number设置过期时间(秒)
mget(...keys) → (string | null)[]批量获取
mset(data) → 'OK'批量设置
ping() → string检测连接是否存活
flushdb() → 'OK'清空当前数据库

对象操作

方法签名说明
setObject(key, value, ttl?) → 'OK'自动 JSON.stringify 后存储
getObject<T>(key) → T | null自动 JSON.parse 后返回

计数器

方法签名说明
incr(key) → number递增 1
incrBy(key, increment) → number递增指定值
decr(key) → number递减 1
decrBy(key, decrement) → number递减指定值

Hash

方法签名说明
hSet(key, field, value) → number设置 Hash 字段
hSetObject(key, data) → number批量设置 Hash 字段
hGet(key, field) → string | null获取 Hash 字段
hGetAll(key) → Record<string, string>获取 Hash 全部字段
hDel(key, ...fields) → number删除 Hash 字段
hExists(key, field) → number判断 Hash 字段是否存在

Set

方法签名说明
sAdd(key, ...members) → number添加成员
sMembers(key) → string[]获取全部成员
sIsMember(key, member) → number判断是否为成员
sRem(key, ...members) → number移除成员
sCard(key) → number获取成员数量

连接状态

方法签名说明
isReady() → boolean连接是否就绪
getClient() → Redis获取底层 ioredis 客户端(高级用法)

特性

  • 自动重连:连接断开后自动重试,最多 10 次,间隔递增(最大 3 秒)
  • 健康检查:定时检测连接状态
  • 优雅关闭:模块销毁时自动断开连接,等待进行中的健康检查完成
  • 懒连接:使用 lazyConnect,不阻塞应用启动

最佳实践

  1. 缓存策略:对频繁访问但不常变化的数据使用缓存,设置合理的 TTL
  2. 对象序列化:使用 setObject / getObject 自动处理 JSON 序列化,避免手动 JSON.parse
  3. 批量操作:利用 mget / mset 减少网络往返,提升性能
  4. 容错降级:Redis 不可用时 try/catch 降级到数据库查询
  5. Key 命名规范:使用 模块:实体:id 格式,如 user:profile:123
typescript
// 推荐的容错模式
@Injectable()
class UserService {
  constructor(
    private readonly cache: CacheService,
    private readonly dao: UserDao
  ) {}

  async getUser(id: string) {
    try {
      const cached = await this.cache.getObject<User>(`user:detail:${id}`)
      if (cached) return cached
    } catch {
      // Redis 不可用时降级:直接走数据库
    }
    const user = await this.dao.findById(id)
    if (user) {
      this.cache.setObject(`user:detail:${id}`, user, 3600).catch(() => {})
    }
    return user
  }
}

健康检查集成

注册 CacheModule 后,HealthModule 会自动检测 Redis 连通性,无需额外配置。

相关文档