Чтение одного и того же кэша с разных микросервисов - PullRequest
0 голосов
/ 21 марта 2019

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

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

Исключение:

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

1 Ответ

0 голосов
/ 22 марта 2019

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

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

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

...