如何在多臺 Web 伺服器上共享 session

linuxMr發表於2018-04-19

比如:現在有三臺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手冊

相關文章