自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一口氣說(shuō)出 4 種分布式一致性 Session 實(shí)現(xiàn)方式,面試杠杠的~

開(kāi)發(fā) 前端 分布式
起初這個(gè)系統(tǒng)的用的人也不多,為了節(jié)省資源,這個(gè)系統(tǒng)僅僅只是單機(jī)部署。后來(lái)隨著用的人越來(lái)越多,單機(jī)已經(jīng)有點(diǎn)扛不住了,于是阿粉決定再部署了一臺(tái)機(jī)器。

[[333096]]

前言

阿粉公司有一個(gè) Web 管理系統(tǒng),使用 Tomcat 進(jìn)行部署。由于是后臺(tái)管理系統(tǒng),所有的網(wǎng)頁(yè)都需要登錄授權(quán)之后才能進(jìn)行相應(yīng)的操作。

起初這個(gè)系統(tǒng)的用的人也不多,為了節(jié)省資源,這個(gè)系統(tǒng)僅僅只是單機(jī)部署。后來(lái)隨著用的人越來(lái)越多,單機(jī)已經(jīng)有點(diǎn)扛不住了,于是阿粉決定再部署了一臺(tái)機(jī)器。

這時(shí)后端系統(tǒng)有兩臺(tái)服務(wù),于是我們使用 Nginx 作為反向代理,整體架構(gòu)圖如下:

這個(gè)架構(gòu)圖想必大家應(yīng)該比較熟悉,現(xiàn)在主流的 Web 系統(tǒng)應(yīng)該都是這么部署。

經(jīng)過(guò)一些調(diào)試之后,在一個(gè)夜深人靜的晚上,阿粉將這套系統(tǒng)部署到了生產(chǎn)。本以為沒(méi)有什么事的,很穩(wěn)的交給測(cè)試小姐姐開(kāi)始測(cè)試。

這一測(cè),出了大問(wèn)題!測(cè)試小姐姐反饋,登錄過(guò)后,沒(méi)過(guò)一會(huì)又需要登錄,操作好幾次都是這樣。

阿粉檢查了一下,系統(tǒng)應(yīng)用,配置什么也沒(méi)問(wèn)題,那到底哪里出了問(wèn)題?

這個(gè)時(shí)候組長(zhǎng)剛準(zhǔn)備下班,看到我們這里有問(wèn)題,于是過(guò)來(lái)了看了一下。簡(jiǎn)單了解的一下基本情況,很快就找到了問(wèn)題的原因,然后在 Nginx 端修改了下配置,重啟解決了問(wèn)題。

分布式一致性 Session

解決完問(wèn)題,組長(zhǎng)坐下給阿粉解釋了問(wèn)題原因:分布式一致性 Session。

原先我們登錄之后將會(huì)把用戶登錄信息放在 Session 中,用戶每次操作首先先校驗(yàn) Session 是否存在用戶信息,如果不存在將會(huì)強(qiáng)制讓用戶先去登錄。

原先架構(gòu)的中我們只有一臺(tái)應(yīng)用系統(tǒng),所有操作都在一臺(tái) Tomcat 上,這當(dāng)然沒(méi)有什么問(wèn)題。

但是現(xiàn)在我們部署了兩臺(tái)系統(tǒng),由于 Nginx 使用默認(rèn)負(fù)載均衡策略(輪詢),請(qǐng)求將會(huì)按照時(shí)間順序逐一分發(fā)到后端應(yīng)用上。

也就是說(shuō)剛開(kāi)始我們?cè)?Tomcat1 登錄之后,用戶信息放在 Tomcat1 的 Session 里。過(guò)了一會(huì),請(qǐng)求又被 Nginx 分發(fā)到了 Tomcat2 上,這時(shí) Tomcat2 上 Session 里還沒(méi)有用戶信息,于是又要登錄。

另外由于我們系統(tǒng)采用單點(diǎn)登錄的方式,Tomcat2 登錄之后會(huì)將 Tomcat1 登錄信息失效,于是乎等到 Nginx 再把流量分發(fā)到 Tomcat1 時(shí),Session 中用戶登錄信息已經(jīng)失效,又要重新登錄。

[[333098]]

知道了問(wèn)題,阿粉當(dāng)然想知道解決辦法了,于是組長(zhǎng)教了阿粉分布式一致性 Session 四種解決辦法,阿粉給大家整理了一下:

 

下面阿粉將會(huì)以阿粉跟組長(zhǎng)對(duì)話的形式,講解分布式一致性 Session 解決辦法。

Session 復(fù)制

組長(zhǎng):

如果此時(shí) Tomcat1 Session 存在用戶信息,而 Tomcat2 上沒(méi)有存在。

這時(shí)如果我們將 Tomcat1 的 Session 復(fù)制到 Tomcat2 上,后面 Nginx 將請(qǐng)求轉(zhuǎn)發(fā)到 Tomcat2 上,由于 Tomcat2 存在 Session ,這時(shí)就不需要再重新登錄了。

架構(gòu)圖如下:

一致性 Session-Session 復(fù)制

Tomcat 的 Session 復(fù)制的配置,網(wǎng)上有比較多的例子,這里阿粉就不再貼了,感興趣的同學(xué)可以自行搜索一下。

阿粉:

對(duì)的,這種方式挺好啊。Tomcat 就支持這種方式,我們只需要修改 Tomcat 配置就好,我們應(yīng)用代碼都不用修改了。

組長(zhǎng):

說(shuō)的對(duì),但是這種方式還是有很多缺點(diǎn)。

第一,Session 復(fù)制傳輸需要占用內(nèi)網(wǎng)帶寬。

第二,我們的例子就只有兩臺(tái)機(jī)器,這個(gè)復(fù)制性能還可以。但是假設(shè)我們有 N 臺(tái)機(jī)器,那么每次復(fù)制都要復(fù)制給 N-1 臺(tái)機(jī)器,如果機(jī)器很多,可能會(huì)形成網(wǎng)絡(luò)風(fēng)暴,復(fù)制性能也會(huì)呈指數(shù)級(jí)下降。

第三, Tomcat 需要保存所有的 Session 數(shù)據(jù),這個(gè)方案的 Session 存儲(chǔ)在內(nèi)存中,容易受到機(jī)器的總內(nèi)存的限制。我們沒(méi)辦法通過(guò)加機(jī)器的方式水平擴(kuò)展,我們能做的方式就是加大機(jī)器內(nèi)存。但是機(jī)器內(nèi)存越大,價(jià)格真的很貴!!!

所以不推薦使用這種方案。

Session 前端存儲(chǔ)

阿粉:

恩,這個(gè)方案確實(shí)有點(diǎn)不靠譜~

哎,有了!我們的 Session 里面其實(shí)就是存了用戶的信息,那我現(xiàn)在不存 Tomcat Session 里,我把信息拿出來(lái),存到瀏覽器的 Cookie 中。

這樣,每個(gè)用戶瀏覽器存儲(chǔ)自己的 Cookie 信息,服務(wù)端就不需要存儲(chǔ),這就解決了 Session 復(fù)制方案的缺陷了。

接下來(lái)用戶每次請(qǐng)求都把這個(gè) Cookie 給我發(fā)過(guò)來(lái),我判斷 Cookie 里面用戶信息不就好了。

架構(gòu)圖如下:

一致性 Session-Session 前端存儲(chǔ)

組長(zhǎng),欣賞看了一下我:

對(duì),你這個(gè)方案確實(shí)可行。

不過(guò)么,如果用這種方案,首先你要想好加密方案。

用戶信息可是我們的敏感數(shù)據(jù),不能讓別人輕易的竊取或者篡改數(shù)據(jù)了。

除了這個(gè),這個(gè)方案每次請(qǐng)求都要攜帶 Cookie 傳輸,這會(huì)占用外網(wǎng)的帶寬,如果 Cookie 過(guò)大,會(huì)增大網(wǎng)絡(luò)的開(kāi)銷。

另外,我們存儲(chǔ)的數(shù)據(jù)大小,容易受到 Cookie 限制。

所以這種還是不怎么常用,不過(guò)也是一種思路。

我比較推薦下面兩種方案。

Session 粘滯(Sticky Sessions)

組長(zhǎng):

剛才應(yīng)該看到了,我只是對(duì) Nginx 的配置做了一些修改,然后這個(gè)問(wèn)題就解決了吧。

其實(shí)這是因?yàn)槲倚薷?Nginx 默認(rèn)的負(fù)載均衡策略,使用 IP Hash 的方式。

Nginx 會(huì)使用請(qǐng)求者的 IP 來(lái)做 Hash,然后分發(fā)到一臺(tái)機(jī)器上,這樣可以保證同一 IP 的請(qǐng)求都落在同一臺(tái) Tomcat 上。

架構(gòu)圖如下:

Session 粘滯-IP Hash

上面這種方式我們使用 Nginx 四層負(fù)載均衡方式,其實(shí) Nginx 還可以做到七層負(fù)載均衡方式,也就是使用 Http 協(xié)議中的一些業(yè)務(wù)屬性來(lái)做 Hash,常見(jiàn)的有 userId,loginId等等。

架構(gòu)圖如下:

一致性 Session-Session 粘滯-七層

阿粉:

這種方案看起來(lái)挺簡(jiǎn)單的,我們只需要修改 Nginx 配置就好了,應(yīng)用端配置無(wú)需改動(dòng)。

只要請(qǐng)求來(lái)源 IP 足夠的隨機(jī),那么 IP HASH 之后兩臺(tái)應(yīng)用上的流量將會(huì)足夠隨機(jī)。

另外后面如果兩臺(tái)機(jī)器扛不住,我們還可以水平擴(kuò)展,再加機(jī)器,只要修改 Nginx 配置即可。

組長(zhǎng):

你說(shuō)的這幾點(diǎn)都很正確!

不過(guò)你有沒(méi)有想過(guò),像我們公司這種情況,所有人的出口的 IP 都是一個(gè)。那么我們公司的所有請(qǐng)求只會(huì)到一臺(tái)機(jī)器上,那我們這種情況等于又變成單點(diǎn)了。

另外如果 Tomcat 重啟,Session 由于是放置在內(nèi)存內(nèi)存中,這一部分的 Session 將會(huì)丟失,這就導(dǎo)致這部分用戶將會(huì)重新登錄。

最后,如果我們臨時(shí)再加機(jī)器,修改完 Nginx 配置,重新啟動(dòng)之后,Nginx 將會(huì)重新計(jì)算 Hash 分發(fā)請(qǐng)求。

這種情況就會(huì)導(dǎo)致有一部分用戶重新路由到一臺(tái)新機(jī)器上,由于沒(méi)有 Session,又需要重新登錄了。

不過(guò)么,Tomcat 重啟或者新加機(jī)器次數(shù)不會(huì)很多,所以這個(gè)問(wèn)題也不大,用戶體驗(yàn)稍差點(diǎn)。

今天的我們這個(gè)問(wèn)題解決方案就先使用這個(gè)。

不過(guò)后面我們還是改成下面這種方式。

后端集中存儲(chǔ)

組長(zhǎng):

上面幾種的方式我們都是把 Session 存儲(chǔ)在應(yīng)用內(nèi)存上,應(yīng)用機(jī)器只要重啟,Session 就會(huì)丟失。

為了這個(gè)解決這個(gè)問(wèn)題,我們將 Session 單獨(dú)存起來(lái),保存到 Redis 或者 MySQL 中。

不過(guò)由于 Session 需要過(guò)期失效的特性,不需要持久化保存,所以這里我建議使用 Redis 來(lái)保存。

這樣架構(gòu)就變成下方這樣的:

一致性 Session-Session 后端存儲(chǔ)

我們使用這種方案,上沒(méi)有 Session 丟失的風(fēng)險(xiǎn),當(dāng)然前提是 Redis 不能宕機(jī)。

另外后期如果應(yīng)用可以直接水平擴(kuò)展。

如果后面應(yīng)用的請(qǐng)求量很大,一臺(tái) Redis 扛不住了,那我們可以其實(shí)可以做集群擴(kuò)展,根據(jù)緩存 Key 做路由。

阿粉:

對(duì)對(duì),這種方式好~

組長(zhǎng):

你不要高興的太早,我們使用這個(gè)方案需要付出一定的代價(jià)的。

首先我們每次請(qǐng)求都需要調(diào)用一次 Redis ,這就增加一次網(wǎng)絡(luò)的開(kāi)銷。

另外,引入 Redis,我們需要對(duì)相應(yīng)的代碼做出修改,這樣復(fù)雜度就變高。

所以說(shuō),這個(gè)方案有利也有弊,當(dāng)然對(duì)于我們的場(chǎng)景來(lái)說(shuō),利大于弊。

阿粉:

恩,好像是這樣的。

組長(zhǎng):

好了,這么晚了,問(wèn)題解決了,我們?nèi)]個(gè)串,我請(qǐng)客!

阿粉:

老大,??!

組長(zhǎng)拍了拍阿粉的腦袋:

我這一頓不是白吃哦,下個(gè)星期你把現(xiàn)在方式修改一下,修改成 Session 集中存儲(chǔ)的方式。

給你一個(gè)小提示,可以使用 spring-session。

阿粉:

好吧,吃人嘴短,下周我研究下。

總結(jié)

最后阿粉總結(jié)一下,當(dāng)我們后端 Web 應(yīng)用擴(kuò)展到多臺(tái)后,我們就會(huì)碰到分布式一致性 Session 的問(wèn)題,主流解決方案有四種:

Session 復(fù)制:利用 Tomcat 等 Web 容器同步復(fù)制

Session 前端存儲(chǔ):利用用戶瀏覽器中 Cookie 保存 Session 信息

Session 粘滯方案:利用 Nginx 可以做四層 Hash 或七層 Hash 的特性,保證用戶的請(qǐng)求都落在同一臺(tái)機(jī)器上

Session 后端集中存儲(chǔ)方案:利用 Redis 集中存儲(chǔ) Session,Web 應(yīng)用重啟或擴(kuò)容,Session 也無(wú)需丟失。

上面四種方案,優(yōu)先推薦第四種。

當(dāng)然第四種方案需要一定的開(kāi)發(fā)工作量,前期還沒(méi)改造的過(guò)程可以選擇 第三種方案中間過(guò)渡。

好了,后面阿粉就要使用 Session 后端存儲(chǔ)方案改造這個(gè)工程了,后面阿粉再跟大家分享一下 spring-session。

 

責(zé)任編輯:武曉燕 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2020-09-24 09:08:04

分布式系統(tǒng)架構(gòu)

2020-04-16 12:42:42

附近的人共享單車App

2020-08-12 09:55:07

附近的人數(shù)據(jù)庫(kù)MySQL

2020-07-31 10:15:32

分布式ID數(shù)據(jù)庫(kù)MySQL

2020-11-04 14:20:58

分布式數(shù)據(jù)庫(kù)MySQL

2020-04-14 13:32:56

@Transacti失效場(chǎng)景

2022-05-24 11:50:46

延時(shí)消息分布式

2020-03-31 08:12:25

Kafka架構(gòu)數(shù)據(jù)庫(kù)

2020-07-08 07:45:44

OAuth2.0授權(quán)

2020-05-08 10:08:21

延時(shí)隊(duì)列APIDelayQueue

2021-06-08 22:43:07

IPC方式Qt

2021-12-06 08:30:49

SpringSpring Bean面試題

2019-10-11 23:27:19

分布式一致性算法開(kāi)發(fā)

2021-03-29 12:22:25

微信iOS蘋(píng)果

2023-12-18 23:09:25

開(kāi)源優(yōu)化引擎

2021-11-22 16:30:30

分布式一致性分布式系統(tǒng)

2019-09-05 08:43:34

微服務(wù)分布式一致性數(shù)據(jù)共享

2021-07-28 08:39:25

分布式架構(gòu)系統(tǒng)

2017-09-21 10:59:36

分布式系統(tǒng)線性一致性測(cè)試

2020-10-22 12:30:33

MySQL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)