Springboot2 session設置超時時間無效的解決
問題:
今天項目中遇到瞭一個設置時間超時的問題,按SpringBoot2的application.properties更改一直不生效。
解決方案:
- server.*屬性用於控制Spring Boot使用的嵌入式容器 。 Spring Boot將使用ServletWebServerFactory實例之一創建servlet容器的實例。 這些類使用server.*屬性來配置受控的servlet容器(tomcat,jetty等)。
- 當應用程序作為war文件部署到Tomcat實例時, server.*屬性不適用。 它們不適用,因為可以使用預先配置的servlet容器(因為它是遠程運行的服務)。 因此,部署到遠程Tomcat將使server.*屬性無用。
1. 按照網上給的帖子更改配置文件(如果是Jar啟動生效) ,如下:
server: servlet: session: timeout: PT1H # 1小時過期 cookie: max-age: PT1H # 1小時過期
說明:PT1H 意思是設置session失效的時間是1小時。
擴展:Duration
通過查看springboot源碼發現setTimeouot方法,這裡要求傳入Duration的實例
public void setTimeout(Duration timeout) { this.timeout = timeout; }
Duration是在Java8中新增的,主要用來計算日期差值,Duration是被final聲明的,並且是線程安全的。
如果轉換字符串方式,類似於 SimpleDateFormat 的格式化日期方式
Duration 字符串類似數字有正負之分:默認為正,負以’-‘開頭,下面緊接著’PT’, 下面時間字母:
- ‘D’ – 天
- ‘H’ – 小時
- ‘M’ – 分鐘
- ‘S’ – 秒
每個單位都必須由數字開始,且時分秒順序不能亂,比如:PT2H3M2S 等於 -PT-2H-3M-2S。
2. 設置tomcat的session超時
1)在tomcat的conf目錄下,更改servler.xml:
<Context path="/abtest" docBase="/abtest" defaultSessionTimeOut="3600" isWARExpanded="true" isWARValidated="false" isInvokerEnabled="true" isWorkDirPersistent="false"/>
2) 項目中更改web.xml:
<session-config> <session-timeout>20</session-timeout> </session-config>
3)在程序中更改
session.setMaxInactiveInterval(30*60);
當你遇到同樣的問題時,請先看上面的紅字,按順序排查即可。
測試代碼:
@RestController @RequestMapping("/valid-time") public class TestController { @GetMapping("/test") public String validTime(HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(); int sessionTime = session.getMaxInactiveInterval(); return new StringBuilder("sessionTime=").append(sessionTime).toString(); } }
時間不同步導致Spring session失效的巨坑
Linux服務器時間不同步導致Spring session失效的巨坑
由於業務的需要,將原本單機環境轉為集群式環境,為瞭不修改任務所以選擇瞭spring session + redis作為session共享方案。
確認技術方案之後就在網上巴拉巴拉的搜索一堆關於spring session的資料,看瞭一遍沒有發現前人有任何躺坑後,開始著手。
安裝redis過程忽略。
根據資料一步一步的將spring session加入工程,單節點情況項目成功跑起來,沒有報錯,session也成功的寫入瞭redis。
然後為瞭穩妥起見,又在自己電腦上安裝瞭nginx,並部署瞭3個tomcat,一切看起來都那麼完美,多個節點之間完成瞭session共享。
到目前已經完成瞭所有前期準備,就差最後一步瞭。
噩夢開始瞭……
在線上將所有節點部署完成,然後打開瀏覽器順利訪問到應用,當然我們不能僅僅停留在看到頁面完事的地步,怎麼也要登錄登錄吧,於是……
然後……
無數次的輸入用戶密碼,提示登錄成功,最終的結果還是被拒之門外,o(╥﹏╥)o
接下來就是無數的填坑之旅
看日志……
看各種請求請求……
懷疑spring session有BUG……
甚至開啟瞭遠程DEBUG模式調試,終於在萬能的DEBUG模式下看到,spring session的getSession的時候,如果獲取到瞭session,首先會判斷此session有沒有過期,比較的方式也很簡單,就是獲取當前系統時間去和session的過期時間進行比較,如果當前時間小於過期時間,則標識此session沒有過期。看到這裡,瞬間有瞭一股醍醐灌頂之感,小宇宙終於在這裡爆發瞭。
尼瑪—>獲取的session全部是過期的,然後……然後……當然是趕緊跑去看服務器時間,於是……哭瞭o(╥﹏╥)o,原來尼瑪是你坑瞭我……
為瞭紀念這次躺坑之旅,特發此文
另外順便記錄一下Linux服務器時間同步
date命令:
date :查看當前時間,結果如下:Tue Mar 4 01:36:45 CST 2017
date -s 09:38:40 :設置當前時間,結果如下:Tue Mar 4 09:38:40 CST 2017
ntpdate命令:
ntpdate -u ntp.api.bz :網絡時間同步命令
ntp常用服務器:
中國國傢授時中心:210.72.145.44
NTP服務器(上海) :ntp.api.bz
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Request與Session的存值取值操作
- Javaweb會話跟蹤技術Cookie和Session的具體使用
- SpringBoot整合SpringSession實現分佈式登錄詳情
- 使用Filter過濾器中訪問getSession()要轉化
- SpringBoot 整合 Spring-Session 實現分佈式會話項目實戰