1. 程式人生 > >分散式-Session一致性問題

分散式-Session一致性問題

Session
session 會話控制,用於儲存特定使用者會話所需的屬性及配置資訊,
表示為特定的時間間隔,指從註冊登入進入系統到登出退出系統直接經過的時間

http無狀態的協議,
在動態web應用中,協議知道前面的操作和後面操作是不是同一個使用者,業務需要關聯性

問題

單臺tomcat沒有任何問題,但現在是叢集的tomcat,請求不會落到同一個tomcat的session中,因此就存在session不一致問題

這裡寫圖片描述

解決方案

方案一:基於Nginx的ip_hash策略
原理:根據ip做hash計算,同一個ip的請求始終定位到同一臺tomcat

這裡寫圖片描述

nginx配置

upstream sessionTest {
    ip_hash;
    server
192.168.2.177:801; server 192.168.2.177:802; }

niginx 命令

start nginx 
nginx -s reload 

優點:配置簡單,應用沒有相容性的,均勻的 ,便於水平擴充套件
缺點:存在單點故障,會導致部分服務不可用

方案二:伺服器Session複製
原理:Tomcat伺服器建立Session後 通過組播方式把session傳送到組播地址中的其他伺服器上
這裡寫圖片描述

tomcat1 server.xml

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster 
channelSendOptions="8"> //8非同步傳送 <Manager ... session.BackupManager <Membership address="228.0.0.4" <Receiver address="auto" port="5001"

tomcat2 server.xml

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster 
channelSendOptions="8">
//8非同步傳送
<Manager ... session.BackupManager
<Membership address="228.0.0.4"
<Receiver address="auto" port="5002"

web.xml

<distributable/>

優點:應用侵入性低,能適應各種負載均衡策略,tomcat宕機不存在session丟失
缺點:session同步延遲,受限於記憶體資源,大量佔用記憶體和頻寬,不利於水平擴充套件

方案三:Session集中統一管理
原理:Session不由tomcat管理, 統一放到一個地方集中式管理。讀取和寫入Session依賴第三方軟體。例如redis,mongodb,mysql等等。
redis 需要做高可用 叢集 所有節點保證冗餘。

這裡寫圖片描述

新增依賴
spring-session

spring-session-data-redis

redis

jedis

web.xml 配置Filter

<filter>
  <filter-name>springSessionRepositoryFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</fitler-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

spring-applicationContext.xml:

<bean id="redisHttpSessionConfiguration" 
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfig 
<property name="maxInactiveIntervalInSeconds" value="600"/>

<bean id="jedisPoolConfig"

<bean id ="jedisConnectionFactory"

config.properties

reids.hostname=192.168.2.227
redis.port=6379
redis.timeout=3000
redis.pool.maxTotal=100
redis.pool.maxIdle=10

redis命令

修改redis.windows.conf

bind 0.0.0.0
redis-server.exe redis.windows.conf 

redis-cli.exe -h 192.168.2.227 
keys * 
type
hgetall key 

session 儲存結果
這裡寫圖片描述
這裡寫圖片描述
注意:session中的物件必須可序列化。

優點:擴充套件能力強,session不易丟失,適應各種負載均衡策略,
缺點:依賴第三方軟體,有應用侵入性;
無法實現跨域名共享session , 只能在單臺伺服器上共享session , 因為是依賴cookie做的 , cookie 無法跨域;一般是用於多臺伺服器負載均衡時共享Session的,都是同一個域名,你想要的跨域的登入,可能需要SSO單點登入。
應用場景:大型分散式環境首選。

spring-session原理

spring-session本質:覆蓋原有tomcat 容器的HttpSession實現。
這裡寫圖片描述
org.springframework.web.filter.DelegatingFilterProxy 在請求之前 覆蓋tomcat 的httpsession實現,具步驟:

1、SessionRepositoryFilter和JedisConnectionFactory註冊過程
這裡寫圖片描述

2、SessionRepositoryFilter新增到FilterChain
這裡寫圖片描述

3、SessionRepositoryFilter攔截過程
這裡寫圖片描述

4、SessionRepository儲存session資料
這裡寫圖片描述