天天看點

如何在多台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資料。如此,同一個使用者的登入狀态就不會丢失了。 但這樣做,有三大弊端:

  1. 把session資料放到用戶端的cookie中,一般都是重要資料(如使用者id、昵稱等),會存在安全問題,但可以将session資料加密後,再存放到cookie中,來降低安全風險。
  2. 浏覽器對單個cookie的資料量大小限制為4K左右,是以會存在資料量的限制問題。
  3. 影響帶寬性能,降低了頁面的通路速度。在高通路量的情況下,使用者每次請求時,都要将用戶端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手冊