分散式-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資料