我們在此定義的大型網(wǎng)站的要素必須包括高并發(fā)的訪問量和較大的數(shù)據(jù)量,此外本身業(yè)務(wù)和系統(tǒng)的復(fù)雜度也是考察的方面喉恋。大型網(wǎng)站要支撐海量數(shù)據(jù)和非常高并發(fā)的訪問量肪凛,那么它肯定是一個(gè)分布式系統(tǒng)。
下面的演進(jìn)過程將從一個(gè)單機(jī)的交易網(wǎng)站開始說起
單機(jī)(單服務(wù)器)負(fù)載警告缭裆,數(shù)據(jù)庫與應(yīng)用分離
當(dāng)網(wǎng)站放置在公網(wǎng)對外訪問后热芹,訪問量不斷增大褂萧,單臺(tái)服務(wù)器的負(fù)載持續(xù)升高命辖。我們可以想到的就是把數(shù)據(jù)庫與應(yīng)用從一臺(tái)機(jī)器分到兩臺(tái)機(jī)器沟涨。
那么 網(wǎng)站結(jié)構(gòu)會(huì)如下圖所示
調(diào)整以后我們能夠緩解當(dāng)前的系統(tǒng)壓力恤批,不過隨著時(shí)間的推移,訪問量繼續(xù)增加裹赴,系統(tǒng)還是需要繼續(xù)向前演進(jìn)的
應(yīng)用服務(wù)器負(fù)載告警喜庞,如何讓應(yīng)用服務(wù)器走向集群
應(yīng)用服務(wù)器壓力變大時(shí),根據(jù)對應(yīng)的監(jiān)測結(jié)果棋返,可以有針對性的進(jìn)行優(yōu)化延都,我們這里要介紹的是把應(yīng)用從單機(jī)變化為集群的優(yōu)化方式。當(dāng)應(yīng)用服務(wù)器從一臺(tái)變成兩臺(tái)睛竣。兩臺(tái)應(yīng)用服務(wù)器之間沒有直接的聯(lián)系晰房,同時(shí)依賴數(shù)據(jù)庫對外提供服務(wù)。那么我們需要解決以下兩個(gè)問題
- 終端用戶對兩個(gè)服務(wù)器訪問的選擇問題,我們可以通過DNS來解決殊者,也可以通過在應(yīng)用服務(wù)器前增加負(fù)載均衡設(shè)備來解決与境,這里我們選擇第二種
- Session的問題
引入負(fù)載均衡設(shè)備
引入負(fù)載均衡設(shè)備之后的架構(gòu)如圖
在此之后,我們會(huì)遇到Session的問題幽污,下面來詳細(xì)介紹Session問題,以及解決方案
解決應(yīng)用服務(wù)器變?yōu)榧褐蟮腟ession問題
什么是Session
用戶使用網(wǎng)站的服務(wù)簿姨,都需要瀏覽器與Web服務(wù)器多次交互距误,Http協(xié)議本身是無狀態(tài)的,需要基于Http協(xié)議支持回話狀態(tài)(Session State)的機(jī)制扁位,而這樣的機(jī)制應(yīng)該可以使Web服務(wù)器從多次單獨(dú)的Http請求中看到回話准潭,也就是知道那些請求是來自那個(gè)回話的,具體實(shí)現(xiàn)方式是:在回話開始時(shí)域仇,分配一個(gè)唯一回話標(biāo)識(shí)(SessionId)刑然,通過Cookie把這個(gè)標(biāo)識(shí)告訴瀏覽器,以后每次請求的時(shí)候暇务,瀏覽器都會(huì)帶上這個(gè)回話標(biāo)識(shí)來告訴Web服務(wù)器請求是屬于那個(gè)會(huì)話的泼掠,在Web服務(wù)器上,各個(gè)會(huì)話有獨(dú)立的存儲(chǔ)垦细,保存不同會(huì)話的信息择镇,如果遇到禁用Cookie的情況,那么括改,一般的做法就是把這個(gè)會(huì)話標(biāo)識(shí)放到URL的參數(shù)中
當(dāng)應(yīng)用服務(wù)器由一臺(tái)變?yōu)閮膳_(tái)之后腻豌,我們就會(huì)遇到Session的問題了:當(dāng)一個(gè)帶有會(huì)話標(biāo)識(shí)的Http請求到了Web服務(wù)器之后,需要在Http請求的處理過程中找到對應(yīng)的會(huì)話數(shù)據(jù)(Session)嘱能,而問題就在于吝梅,會(huì)話數(shù)據(jù)是需要保存在單機(jī)上的。
如上述架構(gòu)圖所示惹骂,當(dāng)我們訪問網(wǎng)站請求的是左邊的服務(wù)器苏携,那么Session解就會(huì)在左邊的服務(wù)器上創(chuàng)建,如果我們不做處理对粪,就不能保證接下來的每次請求都落到同一邊的服務(wù)器上兜叨,這就是Session的問題。
Session問題的解決方案
1.Session Sticky
在單機(jī)的情況下衩侥,Session會(huì)保存在同一個(gè)機(jī)器上国旷,那么當(dāng)我們變化為多臺(tái)服務(wù)器集群后,我們?nèi)绻鼙WC同一個(gè)會(huì)話的請求都在同一個(gè)Web服務(wù)器上處理茫死,那么對這個(gè)會(huì)話來講跪但,與之前單機(jī)的情況是一樣的。
如果要做到這樣,就需要負(fù)載均衡器能夠根據(jù)每次請求的會(huì)話標(biāo)識(shí)倆進(jìn)行請求轉(zhuǎn)發(fā)屡久,即成為Session Sticky方式
這個(gè)方案本身非常簡單忆首,對于Web服務(wù)器來講,該方案和單機(jī)的情況是一樣的被环,只是我們對負(fù)載均衡器做了處理糙及,這個(gè)方案可以讓同樣Session的請求每次都轉(zhuǎn)發(fā)到同一個(gè)Web服務(wù)器進(jìn)行處理,非常利于針對Session進(jìn)行服務(wù)器本地的緩存筛欢,不過也帶來了如下幾個(gè)問題
- 如果處于會(huì)話狀態(tài)的服務(wù)器宕機(jī)或重啟浸锨,那么這臺(tái)服務(wù)器上的會(huì)話數(shù)據(jù)會(huì)丟失。如果會(huì)話中有登錄數(shù)據(jù)的話版姑,那么用戶就要重新登錄了柱搜。
- 會(huì)話標(biāo)識(shí)是應(yīng)用層的信息,那么負(fù)載均衡器要將同一個(gè)會(huì)話的請求都保存到同一個(gè)Web服務(wù)器上的話剥险,就需要進(jìn)行應(yīng)用層的解析聪蘸,這個(gè)開銷比較大
- 負(fù)載均衡器變?yōu)榱艘粋€(gè)有狀態(tài)的節(jié)點(diǎn),要將會(huì)話保存到具體的Web服務(wù)器的映射表制。和無狀態(tài)的節(jié)點(diǎn)相比健爬,內(nèi)存消耗會(huì)更大,容災(zāi)方面會(huì)更麻煩
2.Session Replication
Session Replication 的實(shí)現(xiàn)方式是在Web服務(wù)器之間增加會(huì)話數(shù)據(jù)的同步么介。通過同步就保證了不同Web服務(wù)器之間的Session數(shù)據(jù)的一致性問題浑劳,一般的應(yīng)用容易都支持Session Replication。與Session Sticky相比夭拌,Session Replication方式對負(fù)載均衡器沒有那么多要求魔熏,不過這個(gè)方案本身也有問題,而且在一些場景下問題非常嚴(yán)重鸽扁。
- 同步Session數(shù)據(jù)造成了網(wǎng)絡(luò)帶寬的開銷蒜绽,只要Session數(shù)據(jù)有變化,就需要將數(shù)據(jù)同步到所有其他機(jī)器上桶现,機(jī)器數(shù)越多躲雅,同步帶來的網(wǎng)絡(luò)帶寬開銷就越大。
- 每臺(tái)Web服務(wù)器都要保存所有的Session數(shù)據(jù)骡和,如果整個(gè)集群的Session數(shù)據(jù)很多(很多人在同時(shí)訪問網(wǎng)站)相赁,每臺(tái)機(jī)器用于保存Session數(shù)據(jù)的內(nèi)存占用會(huì)很嚴(yán)重
這就是Session Replication方案,這個(gè)方案不適合集群機(jī)器數(shù)多的場景慰于,如果只有幾臺(tái)機(jī)器钮科,這個(gè)方案是可行的
3.Session數(shù)據(jù)集中存儲(chǔ)
這種方案從名稱就可以得出,就是將數(shù)據(jù)集中存儲(chǔ)到一個(gè)地方婆赠。而不是保存到那一個(gè)Web服務(wù)器中绵脯,這樣,無論是那臺(tái)Web服務(wù)器或者是那個(gè)Session數(shù)據(jù),最終的修改都發(fā)生在這個(gè)集中存儲(chǔ)的地方蛆挫。而Web服務(wù)器使用Session數(shù)據(jù)時(shí)赃承,也是從這個(gè)集中存儲(chǔ)的地方讀取,這樣的方式悴侵,保證了不同Web服務(wù)器上讀取的Session數(shù)據(jù)是一樣的瞧剖。而存儲(chǔ)Session數(shù)據(jù)的具體放方式,可以使用數(shù)據(jù)庫也可以使用其他分布式存儲(chǔ)系統(tǒng)可免。這個(gè)方案解決了Session Replication中的內(nèi)存占用問題抓于,而對于網(wǎng)絡(luò)帶寬,這個(gè)方案也比Session Replication 要好巴元。不過還是會(huì)有一下問題
- 讀取Session 數(shù)據(jù)引入了網(wǎng)絡(luò)操作毡咏,這相對于本機(jī)的數(shù)據(jù)讀取來說驮宴,增加了時(shí)延和不穩(wěn)定性逮刨,不過我們的通信基本都是發(fā)生在內(nèi)網(wǎng),問題不大堵泽。
- 如果集中存儲(chǔ)Session的機(jī)器或者集群有問題修己,就會(huì)嚴(yán)重影響應(yīng)用
相對于Session Replication,當(dāng)Web服務(wù)器數(shù)量比較大迎罗,Session數(shù)量比較多的時(shí)候睬愤,這個(gè)集中存儲(chǔ)的方案是非常明顯的
Cookie Based
Cookie Based方案對于同一個(gè)會(huì)話的不同請求也是不限制具體的機(jī)器的,這個(gè)方案是通過Cookie來傳遞Session數(shù)據(jù)的纹安。
?? 我們將Session數(shù)據(jù)放在Cookie中尤辱,然后在Web服務(wù)器中從Cookie中生成對應(yīng)的Session數(shù)據(jù)。這個(gè)方案不依賴外部存儲(chǔ)系統(tǒng)厢岂,業(yè)績不存在從外部系統(tǒng)獲取光督,寫入Session數(shù)據(jù)的網(wǎng)絡(luò)時(shí)延和不穩(wěn)定性了。不過這個(gè)方案依然存在不足
- Cookie長度的限制塔粒。我們都知道Cookie是有長度限制的结借,而這也會(huì)限制Session數(shù)據(jù)的長度
- 安全性 。Session數(shù)據(jù)本來都是服務(wù)器端數(shù)據(jù)卒茬,而這個(gè)方案是讓服務(wù)器數(shù)據(jù)到了外部網(wǎng)絡(luò)以及客戶端船老,因此存在安全性上的問題。我們可以對寫入Cookie的Session數(shù)據(jù)做加密圃酵,不過對于安全來說柳畔,物理上不能接觸才是安全的
- 帶寬消耗,這里不是指Web服務(wù)器集群內(nèi)部的帶寬消耗郭赐,而是我們數(shù)據(jù)中心外部的帶寬消耗
- 性能影響荸镊,每次Http請求和響應(yīng)都帶有Session數(shù)據(jù),對Web服務(wù)器來說,在同樣的處理情況下躬存,響應(yīng)的結(jié)果輸出越少张惹,支持的并發(fā)請求就會(huì)越多
小結(jié)
對于Web 服務(wù)器從單機(jī)到多機(jī)情況下的Session問題的解決方案,這四種都是可行的方案岭洲,不過對于大型網(wǎng)站來說宛逗,Session Sticky和數(shù)據(jù)集中存儲(chǔ)是比較好的方案,而這兩個(gè)方案又各有優(yōu)劣盾剩,需要在具體的場景中做出權(quán)衡雷激。
??不管采用的是何種解決方案,我們都可以在一定程度上通過增加Web服務(wù)器來提升應(yīng)用的處理能力告私。