You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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; // 可选,返回给前端查看结果
}

验证步骤

  1. 重启Spring Boot应用,重新触发缓存写入(确保新数据用JSON格式存储)。
  2. 重启NestJS应用,调用/redis-cache接口,此时应该能正常读取到Session数据。
  3. 测试NestJS写入功能:调用cacheService.set后,登录Redis控制台用KEYS *查看新增键,用GET [key]确认值为JSON格式。

这样应该就能解决你的跨应用Redis缓存读写问题了。

内容的提问来源于stack exchange,提问作者Eddy Freeman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 11:07:31