1. 程式人生 > >Nginx的session一致性問題

Nginx的session一致性問題

、我們知道Session的常見形式是會話cookie,即為設定過期時間的cookie,它的預設的生命週期為瀏覽器會話期間,一旦瀏覽器關閉視窗,這個cookie就消失了。其實現機制為:當用戶發起一個請求的時候,伺服器會檢查該請求中是否包含sessionID,如果不包含,則伺服器會生成一個名為JSESSIONID的cookie返回到瀏覽器,(這個cookie存放在記憶體中,並不會存在硬碟)。同時在伺服器端以HashTable的形式寫到伺服器記憶體中;當請求中包含sessionID時,伺服器端會在HashTable中查詢與該session相匹配的資訊,若存在則直接使用該sessionID,否則重新生成新的session。
二、

Session共享:如果網站是存放在一臺機器上,是不存在session共享這個問題的,因為所有的會話資料都在這一臺機器上。但是,現在的網站大部分都是需要做負載均衡的,即需要把使用者的請求分發到不同機器,當然這時會話ID在客戶端是不存在問題的,但是服務端會出現取不到session資料的情況。如下圖:
這裡寫圖片描述
在該架構中,採用Nginx做負載均衡,兩個Tomcat做後端伺服器,假設當客戶端第一次請求時,Nginx將其分發到了Tomcat1,這時候Tomcat1會產生sessionID返回給客戶端,並同時儲存在自己的記憶體中;當客戶端第二次請求時,Nginx將其分發到了Tomcat2,這時便無法取到session。從而就會重新生成session,返回給客戶端,並儲存在自己的記憶體中。兩臺Tomcat中儲存的同一個使用者的session不同,這便是session的一致性問題。
為了解決這個問題,首當其衝,我會想到,將Tomcat1中的session複製到Tomcat2中即可,當然是可以的,但是不方便,因為這裡只有兩臺伺服器,而當後臺伺服器增多時,會很麻煩。從而,便有了如下的解決方法:
這裡寫圖片描述

即,將session分離出來,每個伺服器都是從該session伺服器(叢集)中獲取。這樣以來,新增加的伺服器也只需從session叢集中獲取。
(session叢集可以通過memcached或redis來實現)
關於session叢集的搭建,有興趣的朋友可以私信我,共同探討。