官术网_书友最值得收藏!

1.2.2 Session共享和會話保持

首先我們得了解什么是Session,即會話。

Session在網絡應用中被稱為“會話”,借助它可為服務器端與客戶端系統之間提供必要的交互。因為HTTP本身是無狀態的,所以經常需要通過Session來解決服務器端和瀏覽器端的保持狀態問題。Session是由應用服務器維持的一個服務器端的存儲空間,用戶在連接服務器時,會由服務器生成一個唯一的SessionID,該SessionID被作為標識符來存取服務器端的Session存儲空間。

SessionID這一數據是保存到客戶端的,用cookie保存,用戶提交頁面時會將這一SessionID提交到服務器端,以存取Session數據。服務器也會通過URL重寫的方式來傳遞SessionID的值,因此它不是完全依賴于cookie的。如果客戶端cookie禁用,則服務器可以自動通過重寫URL的方式來保存Session的值,并且這個過程對程序員透明。

1.什么是Session共享

隨著網站業務規模和訪問量的逐步增大,原本由單臺服務器、單個域名組成的迷你網站架構可能已經無法滿足發展需要。此時我們可能會購買更多的服務器,并且以頻道化的方式啟用多個二級子域名,然后根據業務功能將網站分別部署在獨立的服務器上,或者通過負載均衡技術(如HAProxy、Nginx)讓多個頻道共享一組服務器。

如果我們把網站程序分別部署到多臺服務器上,而且獨立為幾個二級域名,由于Session存在實現原理上的局限性(PHP中Session默認以文件的形式保存在本地服務器的硬盤上),這使得網站用戶不得不經常在幾個頻道間來回輸入用戶名和密碼,導致用戶體驗大打折扣;另外,原本程序可以直接從用戶Session變量中讀取的資料(如昵稱、積分、登入時間等),因為無法跨服務器同步更新Session變量,迫使開發人員必須實時讀寫數據庫,從而增加了數據庫的負擔。于是,解決網站跨服務器的Session共享問題的需求變得迫切起來,最終催生了多種解決方案,下面列舉4種較為可行的方案來進行對比和探討。

(1)Session復制

熟悉Tomcat或Weblogic的讀者對Session復制應該是非常了解的。Session復制就是將用戶的Session復制到Web集群內的所有服務器上,Tomcat或Weblogic自身都帶了這種處理機制。但它的缺點也很明顯,Session復制是基于IP組播的,隨著機器數量的增加,網絡負擔呈指數級上升,性能隨著服務器數量的增加而急劇下降,而且很容易引起網絡風暴。所以目前基本上不會考慮采用此種方案。

(2)基于cookie的Session共享

這個方案部分讀者可能比較陌生,但它在大型網站中是被普遍使用了的。其原理是將全站用戶的Session信息加密、序列化后以cookie的方式統一種植在根域名下(如.host.com)。當瀏覽器訪問該根域名下的所有二級域名站點時,會將與域名相對應的所有cookie內容的特性傳遞給它,從而實現用戶的cookie化Session在多服務間的共享訪問。

這個方案的優點是無須額外的服務器資源,缺點是受HTTP協議頭信息長度的限制,僅能夠存儲小部分的用戶信息,同時cookie化的Session內容需要進行安全加解密(如采用DES、RSA等進行明文加解密;再由MD5、SHA-1等算法進行防偽認證),另外它也會占用一定的帶寬資源,因為瀏覽器會在請求當前域名下的任何資源時將本地cookie附加在HTTP頭中傳遞到服務器上。

(3)基于數據庫的Session共享

首選當然是MySQL數據庫,建議使用內存表Heap,以提高Session操作的讀寫效率。這個方案的實用性比較強,它的缺點在于Session的并發讀寫能力取決于MySQL數據庫的性能,同時需要我們自己來實現Session淘汰邏輯,以便定時地從數據表中更新、刪除Session記錄,當并發過高時容易出現表鎖,雖然我們可以選擇行級鎖的表引擎,但不得不否認使用數據庫存儲Session還是有些殺雞用牛刀的架勢。

(4)基于Memcached/Redis的Session共享

Memcached是一款基于Libevent的多路異步I/O技術的內存共享系統,簡單的Key+Value數據存儲模式使其代碼邏輯小巧高效,因此在并發處理能力上占據了絕對優勢。

另外值得一提的是,Memcached的內存Hash表所特有的數據過期淘汰機制,正好與Session的過期機制不謀而合,這就降低了刪除過期Session數據的代碼復雜度。但對比“基于數據庫的存儲方案”,僅邏輯這塊就給數據表帶來了巨大的查詢壓力。

Redis作為NoSQL的后起之秀,經常被拿來與Memcached作對比。Redis作為一種緩存,或者干脆稱為NoSQL數據庫,提供了豐富的數據類型(list、set等),可以將大量數據的排序從單機內存解放到Redis集群中處理,并可以用以實現輕量級消息中間件。在Memcached和Redis的性能比較上,Redis在小于100KB的數據讀寫上速度優于Memcached。在筆者的很多線上系統中,Redis已經取代Memcached存放Session數據了。

2.什么是會話保持

會話保持并非Session共享。

在大多數電子商務應用系統中,或者在需要進行用戶身份認證的在線系統中,一個客戶與服務器經常會經過好幾次的交互過程才能完成一筆交易或一個請求。由于這幾次交互過程是密切相關的,服務器在進行這些交互的過程中,要完成某一個交互步驟往往需要了解上一次交互的處理結果,或者上幾步的交互結果,這就要求所有相關的交互過程都由一臺服務器完成,而不能被負載均衡器分散到不同的服務器上。

而這一系列相關的交互過程可能是由客戶到服務器的一個連接的多次會話完成的,也可能是在客戶與服務器之間由多個不同連接里的多次會話完成的。關于不同連接的多次會話,最典型的例子就是基于HTTP的訪問,一個客戶完成一筆交易可能需要多次點擊,而一個新的點擊產生的請求,可能會重用上一次點擊建立起來的連接,也可能是一個新建的連接。

會話保持就是指在負載均衡器上有這樣一種機制,可以識別客戶與服務器之間交互過程的關聯性,在做負載均衡的同時,還能保證一系列相關聯的訪問請求被分配到同一臺服務器上。

主站蜘蛛池模板: 奉贤区| 高密市| 抚顺市| 宣威市| 运城市| 安达市| 泰安市| 长丰县| 宁德市| 滁州市| 吉安市| 安徽省| 乌拉特后旗| 吉水县| 铜陵市| 尼勒克县| 安西县| 衡南县| 米泉市| 通城县| 宁波市| 景泰县| 营山县| 胶州市| 芷江| 林芝县| 荣成市| 酒泉市| 长治市| 南阳市| 蒙自县| 涞源县| 牡丹江市| 嘉善县| 射洪县| 沙雅县| 阿尔山市| 噶尔县| 庄河市| 陈巴尔虎旗| 五河县|