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

时间:2019-03-21 06:17:03

标签: spring-boot spring-data-redis azure-redis-cache

Am使用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;
}

微服务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;
}

两种服务中的缓存方法

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

两个服务中的员工类别

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

1 个答案:

答案 0 :(得分:0)

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

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

  

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