分散式session的解決方案
參考:
https://blog.csdn.net/qq_35620501/article/details/95047642
https://www.cnblogs.com/daofaziran/p/10933221.html
https://www.cnblogs.com/l199616j/p/11195667.html
4種分散式session解決方案
cookie和session的區別和聯絡
cookie是本地客戶端用來儲存少量資料資訊的,儲存在客戶端,使用者能夠很容易的獲取,安全性不高,儲存的資料量小
session是伺服器用來儲存部分資料資訊,儲存在伺服器,使用者不容易獲取,安全性高,儲存的資料量相對大,儲存在伺服器,會佔用一些伺服器資源,但是對於它的優點來說,這個缺點可以忽略了
session有什麼用
在一次客戶端和伺服器為之間的會話中,客戶端(瀏覽器)向伺服器傳送請求,首先cookie會自動攜帶上次請求儲存的資料(JSESSIONID)到伺服器,伺服器根據請求引數中的JSESSIONID到伺服器中的session庫中查詢是否存在此JSESSIONID的資訊,如果存在,那麼伺服器就知道此使用者是誰,如果不存在,就會建立一個JSESSIONID,並在本次請求結束後將JSESSIONID返回給客戶端,同時將此JSESSIONID在客戶端cookie中進行儲存
客戶端和伺服器之間是通過http協議進行通訊,但是http協議是無狀態的,不同次請求會話是沒有任何關聯的,但是優點是處理速度快
session是一次瀏覽器和伺服器的互動的會話,當瀏覽器關閉的時候,會話就結束了,但是會話session還在,預設session是還保留30分鐘的
分散式session一致性
客戶端傳送一個請求,經過負載均衡後該請求會被分配到伺服器中的其中一個,由於不同伺服器含有不同的web伺服器(例如Tomcat),不同的web伺服器中並不能發現之前web伺服器儲存的session資訊,就會再次生成一個JSESSIONID,之前的狀態就會丟失
4種分散式session解決方案
方案一:客戶端儲存
直接將資訊儲存在cookie中
cookie是儲存在客戶端上的一小段資料,客戶端通過http協議和伺服器進行cookie互動,通常用來儲存一些不敏感資訊
缺點:
- 資料儲存在客戶端,存在安全隱患
- cookie儲存大小、型別存在限制
- 資料儲存在cookie中,如果一次請求cookie過大,會給網路增加更大的開銷
方案二:session複製
session複製是小型企業應用使用較多的一種伺服器叢集session管理機制,在真正的開發使用的並不是很多,通過對web伺服器(例如Tomcat)進行搭建叢集。
存在的問題:
- session同步的原理是在同一個局域網裡面通過傳送廣播來非同步同步session的,一旦伺服器多了,併發上來了,session需要同步的資料量就大了,需要將其他伺服器上的session全部同步到本伺服器上,會帶來一定的網路開銷,在使用者量特別大的時候,會出現記憶體不足的情況
優點:
- 伺服器之間的session資訊都是同步的,任何一臺伺服器宕機的時候不會影響另外伺服器中session的狀態,配置相對簡單
- Tomcat內部已經支援分散式架構開發管理機制,可以對tomcat修改配置來支援session複製,在叢集中的幾臺伺服器之間同步session物件,使每臺伺服器上都儲存了所有使用者的session資訊,這樣任何一臺本機宕機都不會導致session資料的丟失,而伺服器使用session時,也只需要在本機獲取即可
如何配置:
在Tomcat安裝目錄下的config目錄中的server.xml檔案中,將註釋開啟,tomcat必須在同一個閘道器內,要不然收不到廣播,同步不了session
在web.xml中開啟session複製:<distributable/>
方案三:session繫結:
Nginx介紹:
Nginx是一款自由的、開源的、高效能的http伺服器和反向代理伺服器
Nginx能做什麼:
反向代理、負載均衡、http伺服器(動靜代理)、正向代理
如何使用nginx進行session繫結
我們利用nginx的反向代理和負載均衡,之前是客戶端會被分配到其中一臺伺服器進行處理,具體分配到哪臺伺服器進行處理還得看伺服器的負載均衡演算法(輪詢、隨機、ip-hash、權重等),但是我們可以基於nginx的ip-hash策略,可以對客戶端和伺服器進行繫結,同一個客戶端就只能訪問該伺服器,無論客戶端傳送多少次請求都被同一個伺服器處理
在nginx安裝目錄下的conf目錄中的nginx.conf檔案
upstream aaa {
Ip_hash;
server 39.105.59.4:8080;
Server 39.105.59.4:8081;
}
server {
listen 80;
server_name www.wanyingjing.cn;
#root /usr/local/nginx/html;
#index index.html index.htm;
location / {
proxy_pass http:39.105.59.4;
index index.html index.htm;
}
}
缺點:
- 容易造成單點故障,如果有一臺伺服器宕機,那麼該臺伺服器上的session資訊將會丟失
- 前端不能有負載均衡,如果有,session繫結將會出問題
優點:
- 配置簡單
方案四:基於redis儲存session方案
基於redis儲存session方案流程示意圖
引入pom依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-data-starter-redis</artifactId>
</dependency>
配置redis
#redis資料庫索引(預設是0)
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
#預設密碼為空
spring.redis.password=
#連線池最大連線數(負數表示沒有限制)
spring.redis.jedis.pool.max-active=1000
#連線池最大阻塞等待時間(負數表示沒有限制)
spring.redis.jedis.pool.max-wait=-1ms
#連線池中的最大空閒連線
spring.redis.jedis.pool.max-idle=10
#連線池中的最小空閒連線
spring.redis.jedis.pool.min-idle=2
#連線超時時間(毫秒)
spring.redis.timeout=500ms
優點:
- 這是企業中使用的最多的一種方式
- spring為我們封裝好了spring-session,直接引入依賴即可
- 資料儲存在redis中,無縫接入,不存在任何安全隱患
- redis自身可做叢集,搭建主從,同時方便管理
缺點:
- 多了一次網路呼叫,web容器需要向redis訪問
總結:
一般會將web容器所在的伺服器和redis所在的伺服器放在同一個機房,減少網路開銷,走內網進行連線