一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫 - Redis - SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法

SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法

2019-11-15 16:44~~fr@ncis~ Redis

為了保證WEB應(yīng)用的承載能力, 需要對(duì)WEB應(yīng)用進(jìn)行集群處理.這篇文章主要介紹了SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法,需要的朋友參考下吧

WEB應(yīng)用開發(fā)完成后部署到Tomcat或其他容器中供用戶訪問. 小型應(yīng)用在一臺(tái)服務(wù)器上安裝Tomcat并部署WEB應(yīng)用. 隨著訪問量增大, Tomcat的壓力會(huì)越來越大, 直至崩潰. 為了保證WEB應(yīng)用的承載能力, 需要對(duì)WEB應(yīng)用進(jìn)行集群處理.

技術(shù)發(fā)展到今天, 集群/負(fù)載均衡已經(jīng)變的相對(duì)簡單了. 下面用通俗的語言給剛?cè)腴T的同學(xué)介紹下這兩個(gè)概念:

某KFC開業(yè)時(shí)只有一個(gè)點(diǎn)餐窗口(一臺(tái)Tocmat服務(wù)器, 可以節(jié)約成本)對(duì)外提供點(diǎn)餐服務(wù). 應(yīng)對(duì)日常點(diǎn)餐沒有問題, 當(dāng)飯口或者周末時(shí)一個(gè)窗口就會(huì)排起長隊(duì)(高并發(fā)). 不僅顧客有怨言(請(qǐng)求響應(yīng)時(shí)間長, 用戶體驗(yàn)差), 服務(wù)員也會(huì)很累, 終于有一天他累倒了(Tomcat掛掉了).

這時(shí)在側(cè)面增加了一個(gè)窗口(增加一臺(tái)Tomcat服務(wù)器)提供點(diǎn)餐服務(wù), 但是很多顧客不知道新窗口, 依舊在原有窗口排起了長隊(duì)(用戶依舊訪問原來的Tomcat), 這時(shí)需要有一個(gè)人專門站在門口根據(jù)每個(gè)窗口的排隊(duì)情況指引顧客去哪個(gè)窗口點(diǎn)餐(負(fù)載均衡器). 這個(gè)人作用是為了讓各個(gè)窗口的點(diǎn)餐人數(shù)大致相等, 避免有的窗口很忙, 有的很閑. 隨著顧客增加, 點(diǎn)餐窗口也會(huì)相應(yīng)增加(Tomcat越來越多).

  • 集群: 一群服務(wù)器集合在一起提供服務(wù), 上例中多個(gè)點(diǎn)餐窗口(多臺(tái)Tomcat)共同提供點(diǎn)餐服務(wù)就是集群.
  • 負(fù)載均衡: 讓集群中每個(gè)點(diǎn)餐窗口(每個(gè)Tomcat)的負(fù)載情況保持均衡, 不要出現(xiàn)某一個(gè)或幾個(gè)太空閑.

兩個(gè)概念是同時(shí)出現(xiàn)的, 沒有集群的服務(wù)(單一Tomcat)也不存在負(fù)載均衡之說, 集群的服務(wù)沒有負(fù)載均衡會(huì)浪費(fèi)資源.

WEB負(fù)載均衡方案很多, Nginx + Tomcat 是常用的方案之一. Nginx作為負(fù)載均衡器根據(jù)每個(gè)Tomcat的負(fù)載情況進(jìn)行分流.

SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法

  • 每個(gè)Tomcat都相當(dāng)于點(diǎn)餐窗口, 都可以提供點(diǎn)餐服務(wù)
  • 每次要點(diǎn)餐都得先經(jīng)過Nginx
  • Nginx會(huì)根據(jù)每個(gè)窗口的空閑情況進(jìn)行分配用戶去哪個(gè)窗口點(diǎn)餐
  • 第一次在1號(hào)窗口點(diǎn)餐, 點(diǎn)完后馬上再次點(diǎn)餐, 有可能被分配到2號(hào)窗口

下面我們搭建負(fù)載均衡的WEB應(yīng)用

1) 搭建WEB應(yīng)用

準(zhǔn)備WEB應(yīng)用, 用兩個(gè)Tomcat部署, 測試時(shí)為了能夠區(qū)分請(qǐng)求是由哪個(gè)Tomcat進(jìn)行處理, 將Tomcat端口號(hào)作為結(jié)果返回.

?
1
2
3
4
5
6
7
8
/**
 * 獲取部署項(xiàng)目的Tomcat端口號(hào)
 */
@RequestMapping("/port/get")
@ResponseBody
public String getPort(HttpServletRequest request) {
 return String.valueOf(request.getLocalPort());
}

本例中分別使用 5677 , 5688 兩個(gè)端口部署該項(xiàng)目. 訪問 /port/get 請(qǐng)求返回結(jié)果為Tomcat的端口號(hào)

http:// localhost:5677/port/get
http:// localhost:5688/port/get

2) Nginx配置負(fù)載均衡

Window下Nginx安裝比較簡單, 不會(huì)安裝的同學(xué)自行百度, 簡單介紹下Nginx配置文件: nginx.conf

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Nginx進(jìn)程數(shù)
worker_processes 1;
events {
 # 最大并發(fā)鏈接數(shù)
 worker_connections 1024;
}
# Nginx處理HTTP請(qǐng)求相關(guān)的配置
# http不能重復(fù), 全局唯一
http {
 # 虛擬主機(jī), 可配置多個(gè)虛擬主機(jī)
 # Nginx監(jiān)聽88,89,90三個(gè)端口, 可配置三個(gè)server
 server {
 # 端口號(hào), 訪問88端口會(huì)都按照該server下的配置進(jìn)行處理
 listen 88;
 # 主機(jī)名稱
 server_name localhost;
 # 根據(jù)正則表達(dá)式匹配URL, 匹配到的URL按照該location下的配置進(jìn)行處理
 # /代表訪問88端口的所有請(qǐng)求
 location / {
 # 靜態(tài)資源所在根目錄, 會(huì)從該目錄下查找靜態(tài)資源
 # 例: 訪問/a.html, 找到D:/a.html并返回
 root D:/;
 }
 }
 
}

上述配置文件最基礎(chǔ)的Nginx配置, 當(dāng)我們?cè)L問 http://localhost:88 時(shí)會(huì)由Nginx處理, 下面我們配置Nginx的負(fù)載均衡.

配置1)中定義的兩個(gè)tomcat, 在 http 節(jié)點(diǎn)下添加如下代碼:

?
1
2
3
4
5
6
7
8
9
# 定義需要進(jìn)行負(fù)載均衡的服務(wù)器信息
# upstream為關(guān)鍵字, springsession為自定義的名稱
# server為關(guān)鍵字, 代表一個(gè)服務(wù)或服務(wù)(一個(gè)tomcat)
# server的內(nèi)容為服務(wù)器的信息, 形式為ip:端口
# weight定義了服務(wù)器負(fù)載的權(quán)重, 每4次請(qǐng)求有3次轉(zhuǎn)發(fā)到5688, 1次到5677
upstream springsession {
 server localhost:5677 weight=1;
 server localhost:5688 weight=3;
}

配置當(dāng)訪問Nginx的所有請(qǐng)求轉(zhuǎn)發(fā)至兩個(gè)服務(wù)器處理

?
1
2
3
4
5
location / {
 # root D:/;
 # 轉(zhuǎn)發(fā)至名稱為springsession的upstream處理
 proxy_pass http://springsession;
}

3) 測試負(fù)載均衡

訪問 http://localhost:88/port/get , Nginx將請(qǐng)求轉(zhuǎn)發(fā)至兩臺(tái)tomcat中的一個(gè)進(jìn)行處理. 可以發(fā)現(xiàn)請(qǐng)求返回的結(jié)果是不一樣的

SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法

  • 根據(jù)配置的權(quán)重, 每4次訪問有3次由 5688 上, 1次由 5677 處理.
  • 權(quán)重配置只是最終平均值為3/4和1/4, 不一定是前三次訪問都會(huì)由 5688 處理.
  • 不配置weight時(shí), 一次請(qǐng)求兩個(gè)tomcat被分配到的概率各占50%

負(fù)載均衡配置好了, 有這樣一個(gè)問題:

你在1號(hào)窗口點(diǎn)餐時(shí)把鑰匙暫存到該窗口, 下次在點(diǎn)餐可能被分配到2號(hào)窗口或其他窗口(也有可能分配到1號(hào)窗口), 那么在其他窗口取鑰匙顯然是行不通的. 因?yàn)槠渌翱跊]有你的鑰匙. 這時(shí)你只能祈禱能快速把你分配到1號(hào)窗口.

如果保存鑰匙的操作變?yōu)樵赟ESSION中保存信息, 那么當(dāng)你的請(qǐng)求被 Tomcat1 處理時(shí), Tomcat1 會(huì)為你生成一個(gè)SESSION, 你在SESSION里面設(shè)置了信息, 下次你的請(qǐng)求被分配到 Tomcat2 處理, Tomcat2 又會(huì)為你生成一個(gè)SESSION. 這是兩個(gè)獨(dú)立的并且不共享的SESSION. 因此你是不可能的在 Tomcat2 中獲取你在 Tomcat1 中保存的信息.

登錄的原理其實(shí)就是在SESSION中保存登錄狀態(tài), 按照上面的分析, 登錄在集群部署的服務(wù)中就失效了. 在Tomcat1中登錄, 下次訪問Tomcat2, 此時(shí)通過SESSION判斷登錄狀態(tài)得到的一定是未登錄, 還需要再次登錄. 用戶瘋, 你瘋, 老板也會(huì)瘋...

如果有一個(gè)公用位置用來存放東西, 所有的點(diǎn)餐窗口都在公用位置存取顧客物品, 上面的問題就迎刃而解了.

這就是本文重點(diǎn): 統(tǒng)一管理集群下各WEB應(yīng)用的SESSION .

  • 容器的選擇: 我們需要一個(gè)能夠統(tǒng)一存放SESSION的容器. 從以下3點(diǎn)分析, Redis 無疑是最合適的. SESSION是經(jīng)常被讀取的, 因此數(shù)據(jù)庫, 文件系統(tǒng)均不適合, 最好是從內(nèi)存操作. SESSION是有ID的, 一個(gè)ID對(duì)應(yīng)一個(gè)SESSION, 最好是一個(gè)K/V的容器 SESSION是有時(shí)效性的(時(shí)間長不用, 需要?jiǎng)h除). 最好能夠設(shè)置過期時(shí)間
  • SESSION存取機(jī)制: 由于SESSION是Tomcat生成的, 因此首先想到的是修改Tomcat的SESSION機(jī)制, 從 Redis 中存取SESSION, 這樣會(huì)帶來一個(gè)問題, 假設(shè)Tocmat升級(jí)了, 我們還需要重新對(duì)Tomcat進(jìn)行修改. 因此這個(gè)方案可行性較差. 我們可以這樣考慮, 即使Tomcat生成了SESSION, 我們也是在WEB應(yīng)用中使用, 為什么不在WEB應(yīng)用中重新生成一個(gè)SESSION呢, 編寫這樣一個(gè)過濾器, 在進(jìn)入WEB應(yīng)用之前, 拋棄Tomcat的SESSION, 從 Redis 中獲取SESSION.

恰巧有這樣一個(gè)框架幫助我們完成上面的想法, 只需要配置一下即可實(shí)現(xiàn)統(tǒng)一管理SESSION. 他就是 Spring Session .

為了對(duì) Spring Session 的功能印象深刻, 我們先來測試一下沒有Spring Session時(shí)我們的集群應(yīng)用是怎樣處理SESSION的

把我們負(fù)載均衡的WEB應(yīng)用中增加一個(gè)控制器方法, 把每次的 SESSION ID 輸出一下.

?
1
2
3
4
5
6
7
8
9
10
11
/**
 * 獲取部署項(xiàng)目的SESSION ID
 */
@RequestMapping("/sessionid/get")
@ResponseBody
public String getPort(HttpServletRequest request, HttpSession session) {
 int port = request.getLocalPort(); // 端口
 String sessionId = request.getSession().getId(); // SESSION ID
 
 return "port: " + port + ", session id: " + sessionId;
}

啟動(dòng)項(xiàng)目, 多次訪問 http://localhost:88/sessionid/get

SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法

兩次訪問都在同一Tomcat下的SESSOIN ID是不變的
兩次訪問在不同的Tomcat下的SESSION ID是變化的
訪問不同的Tomcat后, 再次訪問同一Tomcat時(shí)SESSION ID也是變化的

出現(xiàn)上述情況的原因如下:

  1. 訪問 5677 , 由于沒有SESSION, Tomcat5677 生成SESSION, ID為 1 , 并將 1 返回客戶端
  2. 訪問 5677 , 瀏覽器攜帶 SESSION_ID=1 , Tomcat5677 找到對(duì)應(yīng)的SESSION. 因此SESSION_ID為 1
  3. 訪問 5688 , 瀏覽器攜帶 SESSION_ID=1 , Tomcat5688 找不到對(duì)應(yīng)的SESSION, 重新生成SESSION, ID為 2 , 并將 2 返回客戶端
  4. 訪問 5677 , 瀏覽器攜帶 SESSION_ID=2 , Tomcat5677 找不到對(duì)應(yīng)的SESSION, 重新生成SESSION, ID為 3 , 并將 3 返回客戶端
  5. 訪問 5688 , 瀏覽器攜帶 SESSION_ID=3 , Tomcat5688 找不到對(duì)應(yīng)的SESSION, 重新生成SESSION, ID為 4 , 并將 4 返回客戶端

4) 統(tǒng)一SESSION管理

下面我們來用 Spring Session 來管理WEB應(yīng)用的SESSION

1) 安裝Redis并開啟

參見文章http://m.ythuaji.com.cn/article/28710.html

2) 添加Spring Session依賴

?
1
2
3
4
// Spring Session依賴
"org.springframework.session:spring-session-data-redis:2.0.5.RELEASE",
// Redis依賴
"io.lettuce:lettuce-core:5.0.4.RELEASE"

3) 配置Spring Session過濾器

在 Web.xml 中配置 Spring Session 提供的過濾器, 該過濾器主要負(fù)責(zé)將Tomcat生成的SESSION替換成Redis中保存的SESSION.

?
1
2
3
4
5
6
7
8
9
10
<!-- Spring Session過濾器 -->
<!-- 負(fù)責(zé)在進(jìn)入WEB應(yīng)用之前將Tomcat生成的SESSION替換為Redis中的SESSION -->
<filter>
 <filter-name>springSessionRepositoryFilter</filter-name>
 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
 <filter-name>springSessionRepositoryFilter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

4) SpringSession/Redis配置

在Spring配置文件中增加 Spring Session 配置和 Redis 配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
beans {
 xmlns context: "http://www.springframework.org/schema/context"
 // 啟動(dòng)注解方式
 context.'annotation-config'()
 // 配置Spring Session
 // 實(shí)際上是配置Web.xml中使用的Spring Session過濾器
 // 將Tomcat的Session替換為Redis中管理的Session
 sessionConfig(RedisHttpSessionConfiguration)
 // 配置Redis客戶端連接
 // 默認(rèn)連接本地6379端口
 lettuce(LettuceConnectionFactory)
 
}

5) 測試

啟動(dòng)項(xiàng)目, 多次訪問 http://localhost:88/sessionid/get , 無論如何訪問 SESSION ID 都是一樣的.

SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法

同時(shí) Redis 中也出現(xiàn)了當(dāng)前SESSION的記錄.

SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法

使用 Spring Session 后訪問集群下的WEB應(yīng)用時(shí)SESSION處理過程:

  1. 訪問 5677 , 由于 Redis 中沒有 SESSION , 因此會(huì)生成一個(gè) SESSION 并存入 Redis , ID為 1 , 并將 1 返回客戶端
  2. 訪問 5677 , 瀏覽器攜帶 SESSION_ID=1 , Tomcat5677 在 Redis 中找到了 SESSION . 因此 SESSION_ID 為 1
  3. 訪問 5688 , 瀏覽器攜帶 SESSION_ID=1 , Tomcat5688 在 Redis 中找到了 SESSION . 因此 SESSION_ID 為 1
  4. 清除 Redis , 再次訪問 5677 , 由于 Redis 中沒有ID為 1 的 SESSION , 因此會(huì)重新生成, ID也相應(yīng)變化了

5) 示例代碼

此時(shí)我們已經(jīng)實(shí)現(xiàn)了統(tǒng)一管理SESSION, 無論訪問任一TOMCAT都可以找到相同的SESSION.

當(dāng)我們的應(yīng)用進(jìn)行集群后, 統(tǒng)一管理SESSION勢(shì)在必行, 實(shí)現(xiàn)統(tǒng)一管理SESSION的方式很多, 本文只是其中一種方式. 重在讓同學(xué)們理解統(tǒng)一管理SESSION的重要性和他的基本原理.

示例代碼地址: https://github.com/atd681/alldemo

示例項(xiàng)目名稱: atd681-springsession

總結(jié)

以上所述是小編給大家介紹的SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!

原文鏈接:https://juejin.im/post/5b71a36f6fb9a0099c278af1

延伸 · 閱讀

精彩推薦
  • Redisredis 交集、并集、差集的具體使用

    redis 交集、并集、差集的具體使用

    這篇文章主要介紹了redis 交集、并集、差集的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友...

    xiaojin21cen10152021-07-27
  • Redisredis實(shí)現(xiàn)排行榜功能

    redis實(shí)現(xiàn)排行榜功能

    排行榜在很多地方都能使用到,redis的zset可以很方便地用來實(shí)現(xiàn)排行榜功能,本文就來簡單的介紹一下如何使用,具有一定的參考價(jià)值,感興趣的小伙伴們...

    乘月歸5022021-08-05
  • RedisRedis的配置、啟動(dòng)、操作和關(guān)閉方法

    Redis的配置、啟動(dòng)、操作和關(guān)閉方法

    今天小編就為大家分享一篇Redis的配置、啟動(dòng)、操作和關(guān)閉方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧 ...

    大道化簡5312019-11-14
  • RedisRedis如何實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離詳解

    Redis如何實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離詳解

    Redis的主從架構(gòu),能幫助我們實(shí)現(xiàn)讀多,寫少的情況,下面這篇文章主要給大家介紹了關(guān)于Redis如何實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離的相關(guān)資料,文中通過示例代碼介紹...

    羅兵漂流記6092019-11-11
  • Redisredis中如何使用lua腳本讓你的靈活性提高5個(gè)逼格詳解

    redis中如何使用lua腳本讓你的靈活性提高5個(gè)逼格詳解

    這篇文章主要給大家介紹了關(guān)于redis中如何使用lua腳本讓你的靈活性提高5個(gè)逼格的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具...

    一線碼農(nóng)5812019-11-18
  • RedisRedis 事務(wù)知識(shí)點(diǎn)相關(guān)總結(jié)

    Redis 事務(wù)知識(shí)點(diǎn)相關(guān)總結(jié)

    這篇文章主要介紹了Redis 事務(wù)相關(guān)總結(jié),幫助大家更好的理解和學(xué)習(xí)使用Redis,感興趣的朋友可以了解下...

    AsiaYe8232021-07-28
  • Redis詳解Redis復(fù)制原理

    詳解Redis復(fù)制原理

    與大多數(shù)db一樣,Redis也提供了復(fù)制機(jī)制,以滿足故障恢復(fù)和負(fù)載均衡等需求。復(fù)制也是Redis高可用的基礎(chǔ),哨兵和集群都是建立在復(fù)制基礎(chǔ)上實(shí)現(xiàn)高可用的...

    李留廣10222021-08-09
  • RedisRedis全量復(fù)制與部分復(fù)制示例詳解

    Redis全量復(fù)制與部分復(fù)制示例詳解

    這篇文章主要給大家介紹了關(guān)于Redis全量復(fù)制與部分復(fù)制的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Redis爬蟲具有一定的參考學(xué)習(xí)...

    豆子先生5052019-11-27
主站蜘蛛池模板: 操尼姑| 岛国最新资源网站 | 99福利在线观看 | 国产免费好大好硬视频 | 55夜色66夜亚州精品站 | 天天干夜夜玩 | 星星动漫无删减在线观看 | 精品国产品在线18年 | 成人影院vs一区二区 | 蜜桃视频一区二区 | 国内永久第一免费福利视频 | 日韩一级片在线免费观看 | 国产一区二区三区久久精品 | 好大好猛好爽好深视频免费 | 日本精品一区二区在线播放 | 91进入蜜桃臀在线播放 | 国产精品久久久久久爽爽爽 | 好大好湿好硬好爽好深免费视频 | 99久久国产综合精品1尤物 | 国产目拍亚洲精品一区二区三区 | 欧美a级在线观看 | 男同桌扒开女同桌胸罩喝奶 | 亚洲va国产日韩欧美精品色婷婷 | 俺去俺来也在线www色官网 | 欧美yw193.c㎝在线观看 | 九九影院午夜理论片无码 | 欧美日韩亚洲成人 | 99成人免费视频 | 99精品偷自拍 | 粉嫩高中生第一次不戴套 | 色播影院性播影院私人影院 | 亚洲精品成人A8198A片漫画 | 国产精品吹潮香蕉在线观看 | 天天综合网天天做天天受 | 免费全看男女拍拍拍的视频 | 国产亚洲精品九九久在线观看 | 久久精品无码一区二区日韩av | 99久久精品国产一区二区 | 欧洲网色偷偷亚洲男人的天堂 | 91在线视频播放 | 公园暴露娇妻小说 |