Чтение одного и того же кеша из разных микросервисов

Я использую клиент spring-data-redis(2.1.5.RELEASE) и jedis(2.10.2) для подключения к моему экземпляру azure redis из разных служб, работающих как приложение spring-boot.

Две службы имеют одинаковые методы кэширования и указывают на один и тот же кеш, реализуя следующую конфигурацию. Проблема, с которой я сталкиваюсь, заключается в том, что когда одна служба пытается прочитать кэшированное значение, созданное другой службой, возникает исключение де-серализации.

Исключение:

org.springframework.data.redis.serializer.SerializationException: невозможно десериализовать; вложенным исключением является org.springframework.core.serializer.support.SerializationFailedException: не удалось десериализовать полезную нагрузку. Является ли массив байтов результатом соответствующей сериализации для DefaultDeserializer?; вложенным исключением является org.springframework.core.NestedIOException: не удалось десериализовать тип объекта; вложенным исключением является java.lang.ClassNotFoundException

Примечание. Я использую Redis только для кэширования данных, считанных из моей базы данных.

Redis Cache Конфигурация микросервиса 1

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;
}

Redis Cache Конфигурация микросервиса 2

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; }


person Venkat    schedule 21.03.2019    source источник
comment
Можете ли вы опубликовать точное исключение, которое вы получаете?   -  person Muhammad Inshal    schedule 21.03.2019
comment
@MuhammadInshal Я добавил исключение, с которым столкнулся.   -  person Venkat    schedule 21.03.2019
comment
@Venkat — это два отдельных приложения или одно и то же приложение развернуто дважды?   -  person Jerome    schedule 22.03.2019
comment
@Jerome эти два являются отдельными приложениями, и если одно и то же приложение будет развернуто дважды, служба сможет читать кэшированные данные (которые создаются этой службой)   -  person Venkat    schedule 26.03.2019
comment
Нашел проблему. Имел Employee.java в разных пакетах   -  person Venkat    schedule 28.03.2019


Ответы (1)


Я бы посоветовал вам убедиться, что классы Employee идентичны, а затем добавить в классы поле serialVersionUID. Очистите кэш Redis и повторите попытку.

Это из Javadocs в интерфейсе java.io.Serializable:

Если сериализуемый класс явно не объявляет serialVersionUID, тогда среда выполнения сериализации вычислит значение serialVersionUID по умолчанию для этого класса на основе различных аспектов класса, как описано в Спецификации сериализации объектов Java(TM). Однако настоятельно рекомендуется, чтобы все сериализуемые классы явно объявляли значения serialVersionUID, поскольку вычисление serialVersionUID по умолчанию очень чувствительно к деталям класса, которые могут различаться в зависимости от реализации компилятора, и, таким образом, могут привести к неожиданным InvalidClassException во время десериализации. . Следовательно, чтобы гарантировать согласованное значение serialVersionUID в различных реализациях компилятора Java, сериализуемый класс должен объявить явное значение serialVersionUID. Также настоятельно рекомендуется, чтобы в явных объявлениях serialVersionUID по возможности использовался модификатор private, поскольку такие объявления применяются только к непосредственно объявляющему классу — поля serialVersionUID бесполезны в качестве унаследованных членов.

person Jerome    schedule 22.03.2019
comment
Я добавил serialVersionUID, как вы предложили, но все еще сталкиваюсь с тем же ClassNotFoundException - person Venkat; 26.03.2019