具體的問題
當(dāng)一個帶有會話表示的Http請求到Web服務(wù)器后,需求在請求中的處理過程中找到session數(shù)據(jù)弛针。而問題就在于叠骑,session是保存在單機(jī)上的。 假設(shè)我們有應(yīng)用A和應(yīng)用B削茁,現(xiàn)在一位用戶第一次訪問網(wǎng)站宙枷,session數(shù)據(jù)保存在應(yīng)用A中。如果我們不做處理茧跋,怎么保障接下來的請求每次都請求到應(yīng)用A呢? 如請求到了應(yīng)用B中慰丛,就會發(fā)現(xiàn)沒有這位用戶的session數(shù)據(jù),這絕對是不能容忍的瘾杭。
常見解決方案
Session Sticky
保證同一個會話的請求都在同一個web服務(wù)器上處理诅病,負(fù)載均衡器根據(jù)每次請求的會話表示進(jìn)行轉(zhuǎn)發(fā)。
問題:如果某一臺服務(wù)器宕機(jī)或重啟粥烁,那么這臺服務(wù)器上的session數(shù)據(jù)就丟失了贤笆。如果session數(shù)據(jù)中還有登錄狀態(tài)信息,那么用戶需要重新登錄页徐。負(fù)載均衡要處理具體的session到服務(wù)器的映射苏潜。
Session Replication
web服務(wù)器之間增加會話數(shù)據(jù)的同步,通過同步保證不同web服務(wù)器之間的Session數(shù)據(jù)是一致的变勇。
好處:解決了Session Sticky對負(fù)載均衡的映射要求恤左。
問題:同步Session數(shù)據(jù)造成了網(wǎng)絡(luò)帶寬的開銷,增加每臺機(jī)器的內(nèi)存占用搀绣,不適合集群機(jī)器很多的場景飞袋。
Session數(shù)據(jù)集中存儲
好處:解決了Session Replication方案中內(nèi)存的問題,對于網(wǎng)絡(luò)帶寬也比它要好
問題:讀寫Session數(shù)據(jù)引入網(wǎng)絡(luò)操作链患,存在延時和不穩(wěn)定性巧鸭,發(fā)生在內(nèi)網(wǎng)的話影響不大;如果集中存儲的Session機(jī)器或集群出問題則影響我們的應(yīng)用
Cookie Based
把Session數(shù)據(jù)放在Cookie中麻捻,然后在Web服務(wù)器上從Cookie中生成對應(yīng)的Session數(shù)據(jù)
好處:不會依賴外部的存儲系統(tǒng)纲仍,不存在從外部系統(tǒng)讀寫Session數(shù)據(jù)的網(wǎng)絡(luò)時延呀袱、不穩(wěn)定問題。
問題:Cookie長度限制了Session數(shù)據(jù)長度郑叠;存在安全性問題夜赵;增加數(shù)據(jù)中心的整體外部帶寬消耗;性能影響乡革。
這4種方案都是可用的方案寇僧,不過這4種方案都各有優(yōu)劣,需要根據(jù)具體的實(shí)際場景做出合適的選擇
我們的方案
域名
統(tǒng)一級域名沸版,*.aa.com嘁傀,確保cookie數(shù)據(jù)從瀏覽器傳遞給集群服務(wù)器
會話
- 格式:鍵值對
Key:cookie值
Value:User對象序列化(包括用戶信息、權(quán)限视粮、店鋪细办、企業(yè)信息等) - 全局會話
應(yīng)用服務(wù)器遠(yuǎn)程訪問,創(chuàng)建時設(shè)置過期時間t1(分鐘)馒铃,每次訪問修改過期時間 - 本地會話
應(yīng)用服務(wù)器本地訪問蟹腾,創(chuàng)建時設(shè)置過期時間t2,每次訪問不修改這個過期時間区宇,且t2<t1娃殖,盡量使t2隔一段時間就過期,過期后去訪問遠(yuǎn)程緩存议谷,重新修改時間t1.
運(yùn)行原理
- 用戶登錄炉爆,保存會話數(shù)據(jù)至遠(yuǎn)程緩存服務(wù)器,并設(shè)置會話過期時間卧晓,當(dāng)前系統(tǒng)時間+T1芬首;
- 用戶第一次訪問應(yīng)用服務(wù)器,應(yīng)用服務(wù)器上無會話數(shù)據(jù)逼裆,須從遠(yuǎn)程緩存服務(wù)器獲取會話數(shù)據(jù)郁稍,同時保持會話至本地,并設(shè)置本地會話過期時間胜宇,當(dāng)前時間+T2耀怜,并重新設(shè)置遠(yuǎn)程緩存會話過期時間,當(dāng)前系統(tǒng)時間+T1桐愉;
- 用戶第二次訪問應(yīng)用服務(wù)器财破,應(yīng)用服務(wù)器本地存在會話數(shù)據(jù),直接從本地獲取會話數(shù)據(jù)从诲;
- 應(yīng)用服務(wù)器上本地緩存的會話數(shù)據(jù)過期自動后失效
- 遠(yuǎn)程緩存服務(wù)上的會話數(shù)據(jù)過期后自動失效
會話更新
- 如果在應(yīng)用服務(wù)A中進(jìn)行會話(key=”xxx”)更新左痢,如權(quán)限范圍變大。
- 更新遠(yuǎn)程緩存中會話數(shù)據(jù),服務(wù)器可以生成新的cookie值作為key俊性。
- 從遠(yuǎn)程緩存獲取此會話的原值略步,從值中獲取保存過此會話緩存的其他應(yīng)用服務(wù)器列表,服務(wù)器A以遠(yuǎn)程調(diào)用方式通知其他服務(wù)器刪除本地會話(key=”xxx”)的緩存定页,以便下次從遠(yuǎn)程緩存重新加載一次最新會話數(shù)據(jù)纳像。
問題
- 本地會話與遠(yuǎn)程會話可能不能完全同步,比如遠(yuǎn)程緩存故障丟失拯勉,本地還有此緩存數(shù)據(jù)。
- 用戶在線列表憔购,按用戶查找會話困難宫峦,緩存服務(wù)器需要進(jìn)行全遍歷全部key.雖然有的緩存服務(wù)器如redis支持key的模糊查詢,但是還是會影響性能急劇下降玫鸟,CPU負(fù)載過高导绷,官方不推薦使用。
- 如果要實(shí)現(xiàn)方便檢索的會話屎飘,如按店鋪妥曲、企業(yè)、用戶钦购、主機(jī)來檢索會話檐盟,只得用關(guān)系數(shù)據(jù)庫或NoSQL數(shù)據(jù)庫來實(shí)現(xiàn)。