前言
如果你正在使用Java開發(fā)Web應(yīng)用,想必你對(duì)HttpSession非常熟悉脂信,但我們知道HpptSession默認(rèn)使用內(nèi)存來管理Session雷滚,如果將應(yīng)用橫向擴(kuò)展將會(huì)出現(xiàn)Session共享問題握玛。Spring Session提供了一套創(chuàng)建和管理Servlet HttpSession的方案望门,以此來解決Session共享的問題,更為重要的是在Spring Boot中使用它極其簡(jiǎn)單男图。
Session共享的問題
HttpSession是通過Servlet容器創(chuàng)建和管理的示姿,像Tomcat/Jetty都是保存在內(nèi)存中的。如果我們將Web應(yīng)用橫向擴(kuò)展搭建成分布式的集群逊笆,然后利用LVS或Nginx做負(fù)載均衡栈戳,那么來自同一用戶的Http請(qǐng)求將有可能被負(fù)載分發(fā)到兩個(gè)不同的實(shí)例中去,如何保證不同實(shí)例間Session共享成為一個(gè)不得不解決的問題览露。
最簡(jiǎn)單的解決方法就是把Session數(shù)據(jù)保存到內(nèi)存以外的一個(gè)統(tǒng)一的地方荧琼,例如Memcached/Redis中。那么問題又來了差牛,如何替換掉Servlet容器創(chuàng)建和管理HttpSession的實(shí)現(xiàn)呢?
- 利用Servlet容器提供的插件功能堰乔,自定義HttpSession的創(chuàng)建和管理策略偏化,并通過配置的方式替換掉默認(rèn)的策略。不過這種方式有個(gè)缺點(diǎn)镐侯,就是需要耦合Tomcat/Jetty等Servlet容器的代碼侦讨。這方面其實(shí)早就有開源項(xiàng)目了,例如memcached-session-manager苟翻,以及tomcat-redis-session-manager韵卤。暫時(shí)都只支持Tomcat6/Tomcat7。
- 配置Nginx的負(fù)載均衡算法為ip_hash崇猫,這樣每個(gè)請(qǐng)求按訪問IP的hash結(jié)果分配沈条,這樣來自同一個(gè)IP的訪客固定訪問一個(gè)后端服務(wù)器,有效解決了動(dòng)態(tài)網(wǎng)頁存在的Session共享問題
- 如果你使用Shiro管理Session诅炉,可以用Redis來實(shí)現(xiàn)Shiro 的SessionDao接口蜡歹,這樣Session便歸Redis保管屋厘。
- 設(shè)計(jì)一個(gè)Filter,利用HttpServletRequestWrapper月而,實(shí)現(xiàn)自己的 getSession()方法汗洒,接管創(chuàng)建和管理Session數(shù)據(jù)的工作。Spring-Session就是通過這樣的思路實(shí)現(xiàn)的父款。
在Spring Boot中 集成 Spring Session
Spring Session 支持使用Redis溢谤、Mongo、JDBC憨攒、Hazelcast來存儲(chǔ)Session溯香,這里以Redis為例。
- 引入Maven依賴(本示例使用
dependencyManagement
浓恶,如果你沒有使用它請(qǐng)?zhí)砑?code><version>標(biāo)簽)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
</dependency>
- 配置你的Spring Application玫坛,將你的
application.properties
加入以下配置。
spring.session.store-type=redis
僅此兩步包晰,便集成完畢湿镀,整個(gè)過程完全無痛、無感~
<small>注意:如果你的Redis服務(wù)器不是使用本地默認(rèn)配置(localhost:6379
)伐憾,需要配置你的Redis勉痴,如何配置?看這里树肃。</small>
我們來驗(yàn)證一下~
果然蒸矛,Http Session
已被Spring Session
進(jìn)行包裝,我們可以依舊使用Http Session
的API來進(jìn)行編程胸嘴。
Cookies 也正常創(chuàng)建雏掠,Key為SESSION。
127.0.0.1:6379> keys *
1) "spring:session:sessions:083706a8-b2d8-480c-8b88-eafc798e7269"
2) "spring:session:sessions:expires:083706a8-b2d8-480c-8b88-eafc798e7269"
3) "spring:session:expirations:1490263320000"
使用redis-cli查看劣像,發(fā)現(xiàn)Redis中也已保存相關(guān)數(shù)據(jù)乡话。