NestJS集成KeyV访问Redis缓存异常:无法读取Spring Boot写入的Session缓存数据
解决Spring Boot与NestJS跨应用Redis缓存读写问题
看起来你遇到的问题主要来自两个核心点:Spring Boot与NestJS的缓存序列化格式不兼容,以及NestJS侧的Redis缓存配置有误。我来一步步帮你解决:
1. 修复NestJS的Redis缓存配置
你当前用@keyv/redis的方式不对,cache-manager有专门的Redis存储适配器,推荐使用官方维护的cache-manager-redis-yet,它能正确适配cache-manager的API。
第一步:安装依赖
先卸载没用的依赖,安装正确的包:
npm uninstall @keyv/redis npm install cache-manager-redis-yet redis
第二步:重构SharedModule的缓存配置
把原来的RedisModule和SharedModule里的重复配置合并,确保全局缓存管理器使用Redis:
import { CacheModule } from '@nestjs/cache-manager'; import { redisStore } from 'cache-manager-redis-yet'; import { Module } from '@nestjs/common'; import { CacheService } from './cache.service'; @Module({ imports: [ CacheModule.registerAsync({ isGlobal: true, // 全局生效,避免重复配置 useFactory: async () => ({ store: await redisStore({ url: 'redis://localhost:6379', // 可选:如果你的Redis有密码,添加password字段 // password: 'your-redis-password' }), }), }), ], providers: [CacheService], exports: [CacheService], }) export class SharedModule {}
这样配置后,你的CacheService会自动使用Redis作为存储,而不是默认的内存存储。
2. 统一Spring Boot与NestJS的序列化格式
Spring Boot默认用JDK序列化存储Redis值,这种格式NestJS根本解析不了,所以必须改成JSON序列化,让两边格式一致。
修改Spring Boot的缓存配置
添加一个缓存配置类,指定用Jackson序列化Session对象:
import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration @EnableCaching public class CacheConfig { @Bean public RedisCacheConfiguration redisCacheConfiguration() { return RedisCacheConfiguration.defaultCacheConfig() // 键用字符串序列化 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) // 值用JSON序列化,自动适配实体类 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); } }
如果你的Session类有日期等特殊字段,可以在字段上添加@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解,确保Jackson能正确序列化/反序列化。
3. 修正NestJS控制器的异步调用
你的getDataFromRedis方法没有用async/await,cacheService.get返回的是Promise对象,直接console.log会输出Promise而不是实际值,所以要修改:
@Get("redis-cache") async getDataFromRedis() { const cacheKey = "doubleCachingCache::cache_user_id_34929554-55c0-43cc-8d1f-9c4937df1b76"; const dataFromRedis = await this.cacheService.get(cacheKey); console.log("从Redis读取的数据:", dataFromRedis); return dataFromRedis; // 可选,返回给前端查看结果 }
验证步骤
- 重启Spring Boot应用,重新触发缓存写入(确保新数据用JSON格式存储)。
- 重启NestJS应用,调用
/redis-cache接口,此时应该能正常读取到Session数据。 - 测试NestJS写入功能:调用
cacheService.set后,登录Redis控制台用KEYS *查看新增键,用GET [key]确认值为JSON格式。
这样应该就能解决你的跨应用Redis缓存读写问题了。
内容的提问来源于stack exchange,提问作者Eddy Freeman
相关产品推荐
相关产品推荐

