Node + Redis 實現分佈式Session方案(轉載)

 

Session是什麼?

Session 是面向鏈接的狀態信息,是對 Http 無狀態協議的補充。javascript

Session 怎麼工做?

Session 數據保留在服務端,而爲了標識具體 Session 信息指向哪一個鏈接,須要客戶端傳遞向服務端發送一個鏈接標識,好比存在Cookies 中的session_id值(也能夠經過URL的QueryString傳遞),服務端根據這個id 存取狀態信息。html

在服務端存儲 Session,能夠有不少種方案:java

  1. 內存存儲
  2. 數據庫存儲
  3. 分佈式緩存存儲

分佈式Session

隨着網站規模(訪問量/複雜度/數據量)的擴容,針對單機的方案將成爲性能的瓶頸,分佈式應用在所不免。因此,有必要研究一下 Session 的分佈式存儲。node

如前述, Session使用的標識實際上是客戶端傳遞的 session_id,在分佈式方案中,通常會針對這個值進行哈希,以肯定其在 hashing ring 的存儲位置。redis

Session_id

在 Session 處理的事務中,最重要的環節莫過於 客戶端與服務端 關於 session 標識的傳遞過程:算法

  • 服務端查詢客戶端Cookies 中是否存在 session_id
    1. 有session_id,是否過時?過時了須要從新生成;沒有過時則延長過時
    2. 沒有 session_id,生成一個,並寫入客戶端的 Set-Cookie 的 Header,這樣下一次客戶端發起請求時,就會在 Request Header 的 Cookies帶着這個session_id

好比我用 Express, 那麼我但願這個過程是自動完成的,不須要每次都去寫 Response Header,那麼我須要這麼一個函數(摘自樸靈的《深刻淺出Node.js》):數據庫

這個函數替換了writeHead,在每次Response寫Header時它都會獲得執行機會,因此它是自動化的。這個req.session.id 是怎麼獲得的,稍候會有詳細的代碼示例。json

Hashing Ring

hashing ring 就是一個分佈式結點的迴路(取值範圍:0到232 -1,在零點重合):Session 應用場景中,它根據 session_id 的哈希值,按順時針方向就近安排一個大於其值的結點進行存儲。緩存

Hashing Ring
實現這個迴路的算法多種多樣,好比 一致性哈希cookie

個人哈希環實現( hashringUtils.js:

 

配置


配置信息是須要根據環境而變化的,某些狀況下它又是不能公開的(好比Session_id 加密用的私鑰),因此須要一個相似的配置文件( config.cfg:

在Node 中 序列化/反序列化JSON 是件使人愉悅的事,寫個配置讀取器也至關容易(configUtils.js:

 

分佈式Redis 操做

有了上述的基礎設施,實現一個分佈式 Redis 分配器就變得至關容易了。爲演示,這裏只簡單提供幾個操做 Hashes 的方法(redisMatrix.js:

 

分佈式Session操做

session_id 的事務和 分佈式的Redis都有了,分佈式的 Session 操做呼之欲出(sessionUtils.js:

結合 Express 應用

在 Express 中只須要簡單的 use 就能夠了( app.js:

這個被引用的 session 模塊暴露了一些操做 session 的方法,在須要時能夠這樣使用:

 

原網址(http://www.moye.me/2014/09/28/%E5%88%86%E5%B8%83%E5%BC%8Fsession/)

相關文章
相關標籤/搜索