您好,登錄后才能下訂單哦!
這篇文章主要介紹了springboot中如何使用redis和分布式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配置開始--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>${spring-data-redis.version}</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${jedis.version}</version> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <!--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<String, String> redisTemplate(RedisConnectionFactory 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<String,String> 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<String, SysUser> 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共享”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。