標籤:

怎樣在多台Web伺服器上共享Session

在多台web伺服器上共享session的問題,我們可以舉一些案例來說明。比如:現在有三台php伺服器,且實現了負載均衡,如何讓這三台web伺服器共享session數據?

session數據默認是以文件的形式保存在web伺服器的磁碟上,一般都是用戶登錄成功的時候,保存session數據。

同一個用戶登錄後,就會將session保存在某個web伺服器上,假設是保存在伺服器A上,該用戶訪問網站的其他頁面時,可能請求的就是伺服器B或伺服器C,但伺服器B或伺服器C上並沒有該用戶的session文件,這樣,就會導致網站誤認為該用戶未登錄,用戶的登錄狀態丟失的問題。

歸根結底,就是要解決多台web伺服器共享session的問題,筆者為我們簡要總結了三種方法:

一、將本該保存在web伺服器磁碟上的session數據保存到cookie中

即用cookie會話機制替代session會話機制,將session數據保存到客戶端瀏覽器的cookie中,這樣同一個用戶訪問同一網站時,無論負載均衡到哪台web伺服器,都不用再去伺服器請求session數據,而直接獲取客戶端cookie中的session數據。如此,同一個用戶的登錄狀態就不會丟失了。

但這樣做,有三大弊端:

把session數據放到客戶端的cookie中,一般都是重要數據(如用戶id、昵稱等),會存在安全問題,但可以將session數據加密後,再存放到cookie中,來降低安全風險。

瀏覽器對單個cookie的數據量大小限制為4K左右,因此會存在數據量的限制問題。

影響帶寬性能,降低了頁面的訪問速度。在高訪問量的情況下,用戶每次請求時,都要將客戶端cookie中的session數據發送到伺服器,要佔用較多的帶寬,進而影響訪問速度,伺服器帶寬成本增高。

二、將本該保存在web伺服器磁碟上的session數據保存到MySQL資料庫中

sessionid還是利用cookie機制存儲到客戶端,但session數據卻存放在MySQL伺服器上。(需要建立sessionid和session數據行的對應關係)

但這樣做,只適合訪問量比較小的網站。如果網站的訪問量比較大,對MySQL伺服器會造成很大壓力。因為每次用戶請求頁面(即使是刷新頁面)都要查詢MySQL資料庫中的session數據表,進而判斷用戶的登錄狀態和讀取用戶相關信息,勢必會對資料庫伺服器造成很大壓力,這樣就會降低伺服器的響應速度,影響用戶體驗。

三、將本該保存在web伺服器磁碟上的session數據保存到內存資料庫(memcache或redis)中

memcache或redis是基於內存存儲數據的,性能很高,尤其是高並發的情況下尤為合適。主要是因為從內存中讀取數據要比從磁碟讀取數據快很多。

內存資料庫還支持數據過期失效的機制,正好與session的過期機制對應,推薦使用redis內存資料庫,因為它比memcache支持更多的

數據類型,且支持內存數據備份到磁碟。

這裡簡單說一下,後面兩種方法的注意要點:

如果多台web伺服器對應的是不同的域名,為了保證cookie的唯一(同一個cookie在各個域名有效),需要修改php.ini文件中的session.cookie_domain

由於後面兩種方法,屬於用戶自定義的方式管理session,而非默認的文件處理方式,故需修改php.ini中的session.save_handler=user

在開啟session之前(即調用session_start()之前),需要先調用session_set_save_handler,關於session_set_save_handler的具體用法,請參考php手冊。

推薦閱讀:

使用subst命令快速跳轉到工作間
C++中關於跨平台中子線程式控制制的一些心得(2):用於線程的同步的Async容器
Matplotlib設計的基本邏輯
第一篇:關於開發環境

TAG:編程 |