Redis儲存Session方案
所有支援Servlet規範的容器都自帶session管理,於是大多數人都使用HttpSession
介面存放狀態資訊。事實上, servlet的session會使得應用伺服器水平擴充套件變的非常困難。
使用Servlet Session時的妥協方案
Session Replication
這無疑是一種浪費記憶體的方法,對於5臺左右的叢集還可以忍受,如果你需要幾十甚至上百臺叢集,這就完全不可行。
Session Sticky
該方案雖然可以避免上面的問題,但是這完全背離了負載均衡的初衷。假如有A, B伺服器,A處理session為1 ~ 5的請求,B處理session為6 ~ 10的請求,如果某個時間段內,有1 ~ 5 session的使用者訪問需求非常高,而6 ~ 10 session的使用者不怎麼訪問,這樣就會導致A伺服器負載過高而B卻十分清閒,此時負載均衡就失去了意義。
使用Redis進行Session儲存
在應用編寫時應該完全棄用HttpSession
介面,而是將需要儲存的狀態資訊放到Redis中。
生成session id
當用戶登陸時,伺服器生成一個全域性唯一的字串SESSION:日期:20位隨機字串
做為redis中hash資料結構的key名,然後將該標識做為cookie返回給客戶端。 之後該使用者的後續請求都會帶上此cookie, 我們編寫一個filter, 其作用為讀取請求中的標識,從redis中取出該標識對應的資料,然後放到HttpServletRequest
物件中以供後續使用。
session過期
使用redis自帶的過期功能為session id設定過期時間,輕鬆實現session過期。
session追蹤
我們可以將每個使用者的session id記錄下來,如儲存到資料庫中,或者依然放在redis裡,這樣就可以查到某個註冊使用者所有session id, 輕鬆實現踢出登陸功能。
session更新
通過AOP, 在每個請求完後之後,檢查在請求處理過程中有沒有更新session資訊,如果有則將新資料重新整理到Redis中。
將session轉移到redis中後,只要做好redis的運維工作,我們的應用伺服器已經是完全無狀態的了,水平擴充套件時只需要新增機器而不需要改動任何一行程式碼。