在 NestJS 项目中集成 redis
安装依赖
shell
pnpm install @nestjs/cache-manager cache-manager cache-manager-redis-yet redis --save在 linux 服务器上安装 redis 并开启防火墙和安全组
redis数据库密码:MyRedis@123
异步注册 reds
ts
import { Module, CacheModule } from '@nestjs/common';
import * as redisStore from 'cache-manager-redis-yet';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
// 先注册配置模块,读取 .env 文件
ConfigModule.forRoot({ isGlobal: true }),
// 异步注册缓存模块
CacheModule.registerAsync({
isGlobal: true,
useFactory: (configService: ConfigService) => ({
store: redisStore,
host: configService.get('REDIS_HOST', 'localhost'),
port: configService.get('REDIS_PORT', 6379),
password: configService.get('REDIS_PASSWORD', ''),
db: configService.get('REDIS_DB', 0),
ttl: configService.get('REDIS_TTL', 3600),
}),
inject: [ConfigService], // 注入配置服务
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}在 .env 环境变量中配置
shell
# Redis 数据库配置
REDIS_HOST=47.92.68.193
REDIS_PORT=6379
REDIS_PASSWORD=MyRedis@123
REDIS_DB=0
REDIS_TTL=864000使用(方式一:依赖注入)
ts
import { Inject, Injectable } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
@Injectable()
export class TokenService {
// 注入CacheManager实例
constructor(@Inject(CACHE_MANAGER) private readonly cacheManager: Cache) {}
/**
* 存储过期/失效的Token到Redis,并设置单独过期时间
* @param token 失效的Token字符串
* @param ttl 单独过期时间(秒),优先级高于全局TTL
* @returns
*/
async storeExpiredToken(token: string, ttl: number): Promise<void> {
// 核心方法:cacheManager.set(key, value, ttl)
// 这里key为token本身,value可设为标记(如'expired'),ttl为过期时间(秒)
await this.cacheManager.set(
token, // 缓存key(Token唯一标识)
'expired', // 缓存value(标记Token状态)
ttl, // 单独设置过期时间(秒),可选:若不传则使用全局TTL
);
}
/**
* 验证Token是否已过期(是否存在于Redis缓存中)
* @param token 待验证的Token字符串
* @returns boolean(true:已过期,false:有效/未缓存)
*/
async isTokenExpired(token: string): Promise<boolean> {
// 核心方法:cacheManager.get(key)
const cachedToken = await this.cacheManager.get(token);
// 若缓存存在,说明Token已失效;否则有效
return !!cachedToken;
}
/**
* 手动删除Redis中的过期Token(可选)
* @param token 待删除的Token字符串
* @returns
*/
async removeExpiredToken(token: string): Promise<void> {
await this.cacheManager.del(token);
}
}使用(方式二:装饰器)
ts
import { Controller, Get, Param, CacheKey, CacheTTL } from '@nestjs/common';
import { AppService } from './app.service';
@Controller('demo')
export class AppController {
constructor(private readonly appService: AppService) {}
// 为该接口添加缓存,默认使用接口路径作为缓存键
@Get('user/:id')
@CacheTTL(7200) // 单独指定该接口缓存过期时间(秒),覆盖全局配置
async getUserInfo(@Param('id') id: string) {
// 模拟数据库查询(实际业务中替换为真实数据查询)
return {
userId: id,
username: `user_${id}`,
age: Math.floor(Math.random() * 30) + 20,
};
}
// 自定义缓存键名
@Get('article/:id')
@CacheKey('article_') // 缓存键前缀,最终键为 article_{id}
@CacheTTL(86400)
async getArticleInfo(@Param('id') id: string) {
return {
articleId: id,
title: `文章_${id}`,
content: '这是一篇测试文章内容',
createTime: new Date().toISOString(),
};
}
}