美文网首页
GenericJackson2JsonRedisSerializ

GenericJackson2JsonRedisSerializ

作者: 我还是老油条 | 来源:发表于2019-12-27 18:52 被阅读0次

    上周新上线一个功能,灰度验证通过,一上线就大量500,吓得要死,最后发现结果是redis反序列化失败造成的,由于线上是滚动发布,prd1刚发布,prd2.prd3就疯狂报错,因为新的代码里添加的字段,但是老的代码还没上,当读到新的缓存的时候就发现没有字段,反序列化失败,

    临时解决方案,将缓存的名称改掉,新的代码走新缓存,老的走老缓存,上线后问题解决。

    后来在复盘时,发现是redis设置的的序列化未生效,接下来看下报错:

    报错:Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "feeMode" (, not marked as ignorable (20 known properties: "isMovie", "associatedSeason", "viewCount", "author", "area", "commentCount", "score", "favoriteCount", "duration", "cover", "title", "type", "id", "favorite", "year", "category", "upInfo", "status", "likeCount", "brief"])

    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 设置了但是无效

    尝试将其去掉,发现别的缓存序列化会有问题,证明只有我这块有问题。

    周五花了一天的时间,试验出这种方式才可以解决,但是没有得到权威认证,目前自己测试已经没有问题了

    由于redis可以设置默认的过期时间和序列化协议,如图:

    RedisCacheManager.builder(factory)

    //默认有效时间(30分钟)

            .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(30 *60))

    .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)))

    .withInitialCacheConfigurations(cacheConfigMap)

    .build();

    但是有些缓存我们不想使用默认值就需要自己指定:

    Map cacheConfigMap =new LinkedHashMap();

    cacheConfigMap.put(CacheNames.***,RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(10 *60)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())));

    加粗的地方有问题,这里应当使用我们自己定义的GenericJackson2JsonRedisSerializer

    public RedisConfig() {

    this.deserializer = deserializer();

    }

    private GenericJackson2JsonRedisSerializer  deserializer() {

    ObjectMapper mapper =new ObjectMapper();

        mapper.registerModule((new SimpleModule()).addSerializer(new NullValueSerializer(null)));

        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

        return new GenericJackson2JsonRedisSerializer(mapper);

    }

    加粗的地方就是忽略没有的字段

    修改为:

    cacheConfigMap.put(CacheNames.***,RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(10 *60)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(deserializer)));

    再添加字段,老代码走到新缓存也不会报错

    总结下来:其实就是在设置序列化协议的时候没有使用规定的方式,而是自己new了一个新的,这样以前设置的忽略字段就没有生效,

    所以在设置序列化协议的时候,应该使用以前人用过的,而不是自己随意改造。

    相关文章

      网友评论

          本文标题:GenericJackson2JsonRedisSerializ

          本文链接:https://www.haomeiwen.com/subject/keodoctx.html