在這個微服務,分佈式的時代,不少傳統的實現方案變的再也不那麼適用,好比傳統的web服務將session放在內存中的狀況,當web服務作水平擴展部署的時候,session共享就成了須要處理的問題。目前有不少成熟的技術可供咱們選擇,下面簡單介紹最近用到的spring-boot+spring-session實現session共享的方案。java
spring-boot集成spring-session很是簡單,由於spring-boot爲咱們完成了很是多的工做。具體集成步驟以下:web
1、工程繼承spring-boot-starter-parent <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent>
這樣作的好處是咱們接下來引入其餘依賴包能夠不須要考慮版本問題,推薦這樣作,避免本身引入不當致使的兼容性問題。redis
2、引入spring-session依賴包 <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> </dependency>
引入以後,咱們要肯定咱們要將session持久化到哪一種介質中了。由於分佈式session能夠持久化到數據庫、redis、nosql等中,根據存儲方式不一樣,須要引入不一樣的jar包和作不一樣的操做。咱們以redis存儲爲例。spring
3、引入redis依賴包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
因爲咱們使用了spring-boot,因此咱們只須要引入spring-boot-starter-data-redis依賴便可,這樣咱們能夠很好的利用spring-boot開箱即用以及很是方便的配置優點。sql
4、基礎配置
因爲咱們引入了redis,這樣咱們須要在application.properties或者application.yml文件中配置redis鏈接,使用spring-boot咱們能夠很方便配置單點redis,哨兵模式,集羣模式等,簡單起見咱們配置一個單點模式的redis鏈接並採用鏈接池數據庫
spring.redis.port=6379 spring.redis.host=127.0.0.1 spring.redis.pool.max-active=100 spring.redis.pool.max-idle=5 spring.redis.pool.max-wait=60000
完成以上步驟以後,咱們只須要告訴spring開啓redis方式的session存儲便可,這裏有兩種方式能夠實現瀏覽器
方式一、在配置文件中添加一行配置 spring.session.store-type=redis 方式二、在程序啓動類上添加註解 @EnableRedisHttpSession
兩種方式均可以完成開啓spring-session的redis存儲,是否是很是簡單。由於spring-boot的特性,之前不少須要在xml中配置的均可以輕鬆幫咱們搞定。cookie
雖然咱們實現了redis方式存儲的分佈式session,可是在實際場景中可能還有一些須要優化的地方。session
1、修改cookies中sessionId的名字 2、修改session存放在redis中的命名空間 3、修改session超時時間
爲何要這樣作呢,若是咱們有兩套不一樣系統A和B,cookies中session名稱相同會致使同一個瀏覽器登陸兩個系統會形成相互的干擾,例如兩個系統中咱們存放在session中的用戶信息的鍵值爲user。默認狀況下cookies中的session名稱爲JSESSIONID。當咱們登陸A系統後,在同一個瀏覽器下打開B系統,B系統B系統拿到的user實際上並不是本身系統的user對象,這樣會形成系統異常;而若是咱們A、B系統存放用戶信息的鍵值設置爲不相同,例如userA和userB,當咱們登陸A系統後在登陸B系統,咱們打開瀏覽器調試模式方向兩個系統只有一個sessionId,由於咱們沒有對兩者的session名稱以及存儲的命名空間作區分,程序會認爲就是本身可用的session。當咱們推出B系統,註銷session後。發現B系統的session也失效了,由於在redis中JSESSIONID對應的數據已經被設置過時了。app
同理,若是兩個系統想要不一樣的session過時時間,也存在相同的問題。因此,建議不一樣系統,session名稱以及存儲的命名空間設置爲不一樣,固然相同系統的水平擴展實例的狀況除外。
針對命名空間,咱們能夠在配置文件上添加配置解決
spring.session.redis.namespace=xxxx
若是是註解方式的也能夠在註解上設置
@EnableRedisHttpSession(redisNamespace="xxxx")
這樣咱們查看redis中就能夠看到sping-session存儲的key就變成了咱們設置的值。
針對超時時間,註解方式提供了響應的設置
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
可是配置文件方式並無提供響應的直接設置。
咱們能夠採用javaconfig方式自定義策略來設置超時以及設置cookies名稱,以下咱們設置超時時間是1800秒,cookies名爲MYSESSIONID
@Bean public CookieHttpSessionStrategy cookieHttpSessionStrategy(){ CookieHttpSessionStrategy strategy=new CookieHttpSessionStrategy(); DefaultCookieSerializer cookieSerializer=new DefaultCookieSerializer(); cookieSerializer.setCookieName("MYSESSIONID");//cookies名稱 cookieSerializer.setCookieMaxAge(1800);//過時時間(秒) strategy.setCookieSerializer(cookieSerializer); return strategy; }
#最後
經過以上步驟,咱們就完成了分佈式session的集成。相對於傳統的內存方式,分佈式session實現可以更方便水平擴展以及系統維護。對於不想立馬更改系統採用token方式來進行驗證的系統來講是一種簡便、快速、低成本的一種實現思路。
本文地址:「https://yq.aliyun.com/articles/182676?utm_content=m_29523