Redis存儲session共享在遠光天鵲的實踐

有人問,遠光天鵲作爲一個數據集成產品,是怎麼實現會話共享的?
其實我們實現會話共享有很多種方案。

在分佈式集羣應用中通常通過配置會話保持等設置來保證用戶持續訪問,這樣配置具有簡單快捷的優點,但可能會出現應用負載分配不均的情況,從而導致某些節點繁忙,某些節點閒置,而且穩定性有待考量。今天我們來介紹遠光天鵲的另一種實現方案:使用redis存儲來實現session共享。

Spring Session是Spring家族中的一個子項目,Spring Session提供了用於管理用戶會話信息的API和實現。它把servlet容器實現的httpSession替換爲spring-session,專注於解決 session管理問題,Session信息存儲在redis中,可簡單快速且無縫的集成到我們的應用中。

首先,要在web.xml配置過濾器。

springSessionRepositoryFilter
org.springframework.web.filter.DelegatingFilterProxy


springSessionRepositoryFilter
/*

然後,根據文檔實現redis相關配置信息加載。
【代碼片段】-redis相關Bean
以上是根據sping官方幫助文檔操作來使用redis實現Session 共享,但有時候生產環境沒有redis或者redis配置錯誤怎麼辦,這時又要使用此前的舊方案進行會話保持,但是很顯然目前做的這些事只能使用redis 來存儲Session,這就需要我們進行一些改造來滿足沒有redis的環境還能正常啓動的需求。
來看下Spring Session的原理:
Spring Session原理圖
可以看出關鍵點在DelagatingFilterProxy這個入口,閱讀DelegatingFilterProxy的源碼,發現這個類名副其實,就是一個委託過濾器代理,目的是通過配置過濾器的名稱查找真正實現功能的Filter,然後完成該Filter的功能。找不到過濾器時就會直接拋出異常導致整個應用啓動失敗。如果有沒有redis環境,那遠光天鵲數據集成平臺豈不是使用不了?顯然這樣實現是不合理的。

來,我們將原來的代碼進行改造,設置一個@ComponentScan掃描redis配置所在的包,通過自定義excludeFilter來控制是否掃描redis相關的配置Bean,excludeFilter內的邏輯則是嘗試讀取redis配置,沒有配置redis或者嘗試連接redis失敗則不會創建redis配置的相關Bean,也就不會創建SessionRepositoryFilter。
【代碼片段】-設置@ComponentScan
繼承DelegatingFilterProxy,重寫initDelegate和invokeDelegate方法,未找到SessionRepositoryFilter時進入過濾器鏈的下一個過濾器邏輯。
【代碼片段】-重新initDelegate和invokeDelegate方法 這樣我們的遠光天鵲就完美的實現在有redis的情況下使用redis做session共享,和沒有redis的情況下可以使用其他的會話共享方案(不至於無法啓動),遠光天鵲使用redis做會話共享就是這麼簡單。