从不同的微服务读取相同的缓存

Ven*_*kat 5 spring-data-redis spring-boot azure-redis-cache

我使用 spring-data-redis(2.1.5.RELEASE) 和 jedis(2.10.2) 客户端从作为 spring-boot 应用程序运行的不同服务连接到我的 azure redis 实例。

通过实现以下配置,两个服务具有相同的缓存方法并指向相同的缓存。我面临的问题是,当一个服务尝试读取另一服务创建的缓存值时,会发生反序列化异常。

例外:

org.springframework.data.redis.serializer.SerializationException:无法反序列化;嵌套异常是 org.springframework.core.serializer.support.SerializationFailedException:无法反序列化有效负载。字节数组是DefaultDeserializer相应序列化的结果吗?嵌套异常是 org.springframework.core.NestedIOException:无法反序列化对象类型;嵌套异常是 java.lang.ClassNotFoundException

注意:我仅使用 redis 来缓存从数据库读取的数据。

微服务1的Redis缓存配置

public RedisCacheWriter redisCacheWriter(RedisConnectionFactory connectionFactory) {
    return RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
}

@Bean
public RedisCacheManager cacheManager() {
    Map<String, RedisCacheConfiguration> cacheNamesConfigurationMap = new HashMap<>();
    cacheNamesConfigurationMap.put("employers", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(90000)));
    cacheNamesConfigurationMap.put("employees", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(90000)));

    RedisCacheManager manager = new RedisCacheManager(redisCacheWriter(), RedisCacheConfiguration.defaultCacheConfig(), cacheNamesConfigurationMap);
    manager.setTransactionAware(true);
    manager.afterPropertiesSet();

    return manager;
}
Run Code Online (Sandbox Code Playgroud)

微服务2的Redis缓存配置

public RedisCacheWriter redisCacheWriter(RedisConnectionFactory connectionFactory) {
    return RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
}

@Bean
public RedisCacheManager cacheManager() {
    Map<String, RedisCacheConfiguration> cacheNamesConfigurationMap = new HashMap<>();
    cacheNamesConfigurationMap.put("employees", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(90000)));

    RedisCacheManager manager = new RedisCacheManager(redisCacheWriter(), RedisCacheConfiguration.defaultCacheConfig(), cacheNamesConfigurationMap);
    manager.setTransactionAware(true);
    manager.afterPropertiesSet();

    return manager;
}
Run Code Online (Sandbox Code Playgroud)

两个服务中的缓存方法

@Cacheable(value = "employees", key = "#employeesId") public Employee getEmployee(String employeesId) { //methods }

两项服务中的员工类别

public class Employee implements Serializable { private String id; private String name; }

小智 0

我建议您确保 Employee 类是相同的,然后向这些类添加一个 serialVersionUID 字段。清除 Redis 缓存并重试。

这是来自 java.io.Serialized 接口中的 Javadocs:

如果可序列化类未显式声明serialVersionUID,则序列化运行时将根据该类的各个方面计算该类的默认serialVersionUID 值,如Java(TM) 对象序列化规范中所述。但是,强烈建议所有可序列化的类显式声明serialVersionUID值,因为默认的serialVersionUID计算对类细节高度敏感,这些细节可能因编译器实现而异,因此可能会在反 InvalidClassException序列化期间导致意外的s。因此,为了保证在不同的 java 编译器实现之间具有一致的serialVersionUID 值,可序列化类必须声明显式的serialVersionUID 值。还强烈建议显式的serialVersionUID声明private尽可能使用修饰符,因为此类声明仅适用于立即声明的类——serialVersionUID字段作为继承成员没有用处。