獨立實現一個分布式session
對于一個獨立應用來說,單機部署不需要考慮分布式問題,默認的session實現就行了,一旦多機部署,首先我們需要修改session方案,分布式session解決的是多機session狀態同步的問題,一般情況下,會有2種常見的方案
1,簡單點,機器間相互同步,當一臺機器上的session狀態改變后,自動發送請求到其他所有機器上,同步狀態,這樣做當然是可行的,但缺點也很明顯,機器之間的網絡通訊比較頻繁,而且網絡問題會引起某些機器的session狀態未及時同步,導致用戶端訪問出現異常
2,對于多機部署的應用來說,用一臺機器做session服務器,應用集群全部請求這臺session服務器獲取session信息,這樣做避免了狀態同步這種繁瑣的事情,但仍有缺點,當qps很高的情況下,session服務器的網絡壓力會非常大,因為所有請求都會落到這一臺機器上來,一般存儲session信息可以使用redis或者其他分布式cache數據庫來做,如何解決上述問題呢,我的做法是,充分利用每臺應用服務器的內存做一個二級緩存,來緩解session服務器的壓力,只有session信息改變后 application才會去請求session 服務器拉去最新的session信息同步到本機,否則直接讀取本機session返回給客戶端,那如何做呢,大家都知道,瀏覽器是根據sessionid 這個標識傳給服務器讀取session的,我們提出一個跟sessionid同等地位概念,叫版本:session_version,我們將 session_version存儲到cookie中,且在服務端也存儲起來,可以跟sessionid做一個一對一的關聯;ok,當用戶發起請求到服務器改變了session信息后,該服務器讀取cookie中的session_version,對其加一后更新cookie;這時候用戶cookie里的 session_version已經改變,用戶再起請求服務器,可能請求落到其他機器上,那這臺機器先檢查本服務器上的sessionid對應的 session_version版本是否比用戶cookie中的低,如果低,則請求session服務器獲取最新的session,同時更新服務器內存中的session_version到最新版本,如果session_version比對一致,則直接返回服務器本地的session給用戶;
這樣做可以充分環節session服務器的壓力,但對應用server的內存要求就會有些高了,因為要緩存session信息,我推薦應用使用本地緩存存儲session信息,例如ehcache這種的,信息可以同步到硬盤上持久化一下;這個方案適合一些中型業務規模的應用,并不適合超大規模業務場景;
另外還有一個問題,對于一些應用來說,可能某一部分用戶的活躍度很高,導致在這個環形的 hash分布中,hash落點出現聚集效應,結果就是個別機器的存儲量明顯高于其他機器,這樣資源利用和負載明顯不均衡,如何解決這個問題呢,答案是,我們可以再做一次虛擬映射,將每天機器上映射成多個節點,平均地分布到環形區域中,這樣hash落點只是落到虛擬節點上,從而完美滴解決了hash分布不均衡的問題,當然由于再次封裝了一層,這會導致性能上的損失,但這種損失是微乎其微的,可以接受。
來自:http://my.oschina.net/glarystar/blog/465992