全部支持Servlet規範的容器都自帶session管理,因而大多數人都使用HttpSession
接口存放狀態信息。事實上, servlet的session會使得應用服務器水平擴展變的很是困難。redis
這無疑是一種浪費內存的方法,對於5臺左右的集羣還能夠忍受,若是你須要幾十甚至上百臺集羣,這就徹底不可行。數據庫
該方案雖然能夠避免上面的問題,可是這徹底背離了負載均衡的初衷。假若有A, B服務器,A處理session爲1 ~ 5的請求,B處理session爲6 ~ 10的請求,若是某個時間段內,有1 ~ 5 session的用戶訪問需求很是高,而6 ~ 10 session的用戶不怎麼訪問,這樣就會致使A服務器負載太高而B卻十分悠閒,此時負載均衡就失去了意義。服務器
在應用編寫時應該徹底棄用HttpSession
接口,而是將須要保存的狀態信息放到Redis中。cookie
當用戶登錄時,服務器生成一個全局惟一的字符串SESSION:日期:20位隨機字符串
作爲redis中hash數據結構的key名,而後將該標識作爲cookie返回給客戶端。 以後該用戶的後續請求都會帶上此cookie, 咱們編寫一個filter, 其做用爲讀取請求中的標識,從redis中取出該標識對應的數據,而後放到HttpServletRequest
對象中以供後續使用。session
使用redis自帶的過時功能爲session id設置過時時間,輕鬆實現session過時。數據結構
咱們能夠將每一個用戶的session id記錄下來,如保存到數據庫中,或者依然放在redis裏,這樣就能夠查到某個註冊用戶全部session id, 輕鬆實現踢出登錄功能。負載均衡
經過AOP, 在每一個請求完後以後,檢查在請求處理過程當中有沒有更新session信息,若是有則將新數據刷新到Redis中。運維
將session轉移到redis中後,只要作好redis的運維工做,咱們的應用服務器已是徹底無狀態的了,水平擴展時只須要添加機器而不須要改動任何一行代碼。spa