• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

详解springboot中redis的使用和分布式session共享问题

springboot 搞代码 4年前 (2022-01-05) 18次浏览 已收录 0个评论

这篇文章主要介绍了详解springboot中redis的使用和分布式session共享问题,详细的介绍了解决分布式系统的session如何共享问题,有兴趣的可以了解一下

对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash、轮训、根据权重、随机等。不管对于哪一种负载均衡算法,由于Nginx对不同的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不同的容器里,因此会出现session不同步或者丢失的问题。

实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat、Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis)中。

本文旨在解决分布式系统的session如何共享问题,大致思路:session放入redis。其他解决方案:持久化、放cache等都可以,但是自从有了redis,这完全可以变的简简单单。

本文大致分两步:

1.springboot中如何使用redis。
2.redis如何解决session共享

pom依赖

 <!--redis配置开始--> org.springframework.bootspring-boot-starter-redis org.springframework.dataspring-data-redis${spring-data-redis.version} redis.clientsjedis${jedis.version} org.springframework.sessionspring-session-data-redis<!--redis配置结束-->

添加redis配置类

该配置类同样可以配置缓存失效时间等。

 package com.mos.quote.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; /** * @author Administrator */ @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean public KeyGenerator KeyGenerator(){ return (target, method, params) -> { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); }; } @Bean public RedisTemplate redisTemplate(RedisConnectionFacto<em style="color:transparent">来源[email protected]搞@^&代*@码网</em>ry factory) { StringRedisTemplate template = new StringRedisTemplate(factory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } @Bean public CacheManager cacheManager(RedisTemplate redisTemplate) { RedisCacheManager rcm = new RedisCacheManager(redisTemplate); //设置缓存过期时间 rcm.setDefaultExpiration(600000); return rcm; } } 

配置redis服务

 # Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 spring.redis.host=192.168.1.118 # Redis服务器连接端口 spring.redis.port=6381 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=0 

单元测试

1、set值(字符串)

 @Test public void put(){ stringRedisTemplate.opsForValue().set("test001","test001"); Assert.assertEquals("test001", stringRedisTemplate.opsForValue().get("test001")); }

往redis放一个key为test001、value为test001的值,然后查看redis

key=test001

2、set值(object)

 @Test public void testObj() throws Exception { SysUser user=new SysUser(); user.setId("123456"); user.setName("张三"); ValueOperations operations=redisTemplate.opsForValue(); operations.set("user1", user); operations.set("user2", user,5, TimeUnit.SECONDS); Thread.sleep(6000); Assert.assertFalse(redisTemplate.hasKey("user2")); } 

往redis分别放key为user1和user2的对象,user2设置5秒失效,线程等待6秒再完成,期望结果:redis中有user1,没有user2,bingo!!!

ObjTest

解决session共享

使用spring-session-data-redis实现session共享,pom中引入该依赖(上文已添加),添加SessionConfig配置类。
对,没看错,只需要这个就够了。最长有效时间根据自己情况随意配置即可。

 package com.mos.quote.config; import org.springframework.context.annotation.Configuration; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; /** * @author Administrator */ @Configuration @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3000) public class SessionConfig { } 

测试

写一个简单Controller,如下

 @RequestMapping("testSessionTimeOut") public String testSessionTimeOut(String id,HttpSession session,Model model){ Area area = areaService.getById(id); System.out.println("sessionId-------->"+session.getId()); model.addAttribute("area",JSON.toJSONString(area)); session.setAttribute("area",JSON.toJSONString(area)); return "demo/test1"; } 

这里可以看到sessionId:

sessionId

看redis中,可以看到失效时间,sessionId等

sessionId

共享session

另外找一个机器,照着这个配置再来一遍,自动启用session共享,因为sessionId都存在了同一个redis中。奏是这么简单。挽起袖子开始干吧。

以上就是详解springboot中redis的使用和分布式session共享问题的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:详解springboot中redis的使用和分布式session共享问题

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址