解决redis微服务场景下,A服务添加的key,B服务无法获取的问题

发布时间:2022-06-17 20:44:25 作者:yexindonglai@163.com 阅读(1356)

问题描述

公司里需要用到单点登录,因为是springcloud微服务,最方便的方式就是将已登录的用户session数据统一存储到redis中,其他服务的登录状态直接在redis去取就行了,但是公司的业务模块分的比较细,用户是一个服务,订单是一个服务,商品服务又是一个服务;这就导致了我在用户服务登录后,拿token去订单服务校验时取不到redis的数据,

定位问题

通过debug发现,redis的序列化策略有3种

  • JDK序列化 (默认序列化格式,耗时长、可能出现乱码)
  • String序列化,耗时最短,string序列化后,可视化界面还是原样子,但是如果是对象的话,需要自己手动转为对象
  • json序列化,官方实现的是jackson的序列化,此外fastjson也有对应的实现。优点是以键值对方式呈现,可读性好,但是对于hash类型的数据耗时较长

并且可以给key和value都设置不同的序列化方式,

知道这些就可以知道,原来就是我在A服务使用的是String序列化,而在B服务中,用的是JDK序列化,使用了2种不同的序列化方式,自然拿不到数据;所以需要统一序列化方式;

解决方案

现在知道问题,那就着手解决呗,其实也很简单,只需要在每个类种都加一个配置就可以了

  1. package com.bizzan.bitrade.config;
  2. import com.fasterxml.jackson.annotation.JsonAutoDetect;
  3. import com.fasterxml.jackson.annotation.PropertyAccessor;
  4. import com.fasterxml.jackson.databind.ObjectMapper;
  5. import org.springframework.cache.CacheManager;
  6. import org.springframework.cache.annotation.CachingConfigurerSupport;
  7. import org.springframework.cache.annotation.EnableCaching;
  8. import org.springframework.context.annotation.Bean;
  9. import org.springframework.context.annotation.Configuration;
  10. import org.springframework.data.redis.cache.RedisCacheManager;
  11. import org.springframework.data.redis.connection.RedisConnectionFactory;
  12. import org.springframework.data.redis.core.RedisTemplate;
  13. import org.springframework.data.redis.core.StringRedisTemplate;
  14. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
  15. @Configuration
  16. public class RedisCacheConfig {
  17. /**
  18. * RedisTemplate配置
  19. * @param factory
  20. * @return
  21. */
  22. @Bean
  23. public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
  24. StringRedisTemplate template = new StringRedisTemplate(factory);
  25. //定义key序列化方式
  26. //RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型会出现异常信息;需要我们上面的自定义key生成策略,一般没必要
  27. //定义value的序列化方式
  28. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
  29. ObjectMapper om = new ObjectMapper();
  30. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  31. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  32. jackson2JsonRedisSerializer.setObjectMapper(om);
  33. // template.setKeySerializer(redisSerializer);
  34. template.setValueSerializer(jackson2JsonRedisSerializer);
  35. template.setHashValueSerializer(jackson2JsonRedisSerializer);
  36. template.afterPropertiesSet();
  37. return template;
  38. }
  39. }

关键字Redis