因此,我們可以擴展應用程序,添加新節點,刪除節點,而無需考慮會話復制以及消耗的Java堆內存。
最近,我一直在從事高負載REST應用程序。 實際上,我們并不期望在那里有很高的流量,但是令人驚訝的是,我們已經為我們準備了更高的流量(這就是所謂的“快樂問題”)。 應用程序基于Spring框架 ,并通過部署在Apache Tomcat 7上的Spring Security進行保護。 所有資源都是完全無狀態的–我的任何代碼都沒有觸及HttpSession。 不幸的是,直到以下時間為止,用過的Java堆空間一直在增加:
java.lang.OutOfMemoryError: Java heap space
被扔了。 為了分析Java堆轉儲和堆的運行時使用情況,我使用了VisualVM 。

堆轉儲分析顯示, Tomcat使用的ConcurrentHashMaps占用了很大一部分內存來存儲會話。 這些會話對象幾乎是空的,但是它們太多了,以至于它們消耗了約50%的保留Java堆空間。

向Tomcat啟動腳本中添加參數: -XX:+HeapDumpOnOutOfMemoryError
以在java.lang.OutOfMemoryError: Java heap space
上獲取Java堆轉儲
我要做的第一件事是將web.xml
會話超時從默認的30分鐘限制為1分鐘(可能的最低選擇):
<?xml version='1.0' encoding='UTF-8'?>
<web-app xmlns='http://java.sun.com/xml/ns/javaee'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xsi:schemaLocation='http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd'version='3.0'><!-- ... --><session-config><session-timeout>1</session-timeout></session-config>
</web-app>
那解決了問題– GC清理了堆,結果更好,并且不再拋出OutOfMemoryError。 但是更重要的是這些會議來自何處? 答案是:Spring Security。
默認情況下,Spring Security根據需要創建會話-這意味著,如果用戶已成功通過身份驗證,則將創建會話。 就我而言,它意味著–總是如此。 為了防止Spring Security創建會話,需要將create-session='never'
添加到http
:
<http create-session='never'><!-- ... -->
</http>
您可能會認為–空的會話對象應該不是問題。 我可以告訴您,對于每秒處理數百個請求的應用程序來說,它確實是一個改變。 尤其是當它不在云中運行或只有很少的GB或RAM專用于Java堆時。 經過這些修改后,Java堆的用法如下所示:

參考:在軟件開發之旅博客上,我們的JCG合作伙伴 Maciej Walkowiak 解決了REST + Spring Security會話問題 。
翻譯自: https://www.javacodegeeks.com/2012/07/rest-spring-security-session-problem.html