用 Redis 解決 NodeJS 多程式無法共享 session 的問題

Natumsol發表於2016-04-06

背景知識

我們知道後端是通過session來維持使用者的會話的,每當使用者發起一個請求的時候,使用者的瀏覽器就會將使用者的一個sessionIDcookie的形式傳送到後端,後端接收到這個sessionID後,就會看記憶體中有沒有sessionID為此sessionIDsession,如果存在,則授權訪問;否則重定向到授權頁面或者返回錯誤碼。

因為是NodeJS是單執行緒的,為了充分利用CPU的多核特性,採用了cluster模組,利用主從模式,生成與CPU核心數量相當的子程式,然後主程式用來捕獲請求隨機分配給子程式處理,並負責子程式的崩潰重啟。但是,在引進了cluster模組之後,以前的session認證機制將完全不可用。原因如下:

我們知道程式與程式之間是不能共享資料的,所以程式1的記憶體資料無法被程式2讀取到,所以如果使用者A認證的過程是被程式1所處理的,那麼維持會話的session將儲存在程式1的記憶體資料中;如果此使用者接下的請求被程式2所處理,因為程式2沒有處理過使用者A的認證,沒有維持這個會話的session,所以程式2會判斷使用者A並沒有授權。這樣使用者A需要多次重複認證訪問才能繼續下去…

解決方案

我們現在的問題是session無法共享,所以我們可以想辦法讓session共享。通過將session存在基於記憶體的資料庫redis裡面,即可完美的解決了session共享的問題。

現在以Express框架為例,說一下具體做法:

  1. 安裝redis,安裝過程參考 官方文件
  2. 安裝connect-redis模組
  3. 配置Express

    後記

其實,我們也可以換一種思路來解決這個問題。既然多程式之間無法共享session,那就索性不共享唄!放棄cluster,利用系統指令碼開啟與CPU數量相當的NodeJS程式,並且每個程式監聽不同的網路埠,利用Nginx負載均衡機制,設定均衡模式為ip_hash,這樣對於同一個客戶端的請求轉發到同一個埠,避免了將請求轉發到沒有認證的埠,這樣也可以解決此問題。

基本思想如下圖所示:

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

用 Redis 解決 NodeJS 多程式無法共享 session 的問題 用 Redis 解決 NodeJS 多程式無法共享 session 的問題

相關文章