websocket server OOM異常及傳輸大小設置


基於springboot編寫了一個簡單Websocket服務,主要用來接收客戶端上報的各種數據。由於網絡環境不穩定,經常出現websocket連接中斷,客戶端自動重連的現象。

某日,生產環境突然出現上百個客戶端集體掉線的警報,而且是同一時間發生的,平常也就一兩個掉線告警。

起初以為是網絡問題,但從客戶端現象看,一直時連接超時,網絡可以ping通。搜索后台日志,發現大量connection reset異常,並伴有OutOfMemoryError: java heap space (先重啟解決離線了問題)

想辦法在本地重現:調整JVM -Xms500M -Xmx500M

一個客戶端,一直發送消息,通過jconsole發現,jvm堆內存並不會一直增長,大部分數據在沒有進入年老代就被回收了。

連續建立多個客戶端,不中斷連接,很快就出現了OOM,dump內存數據,使用jvisualvm進行簡要分析:

找出最大的對象,如下:竟然全部是WsFrameServer對象,繼續點擊去看下對象細節

 

主要是兩個buffer占用的大量空間!

 

 

 

 

 看源碼,發現端倪,每初始化一個WsFrameServer對象,jvm都要分配maxBinaryMessageBufferSize和maxTextMessageBufferSize的內存,過多的websocket連接,很快就把內存沾滿了。

 

 

 知道了原因,也就有應對方法。減小bufferSize,設置合理的空閑超時時間。

bufferSize設置:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class WebSocketConfig implements ServletContextInitializer{
    
    //配置websocket傳輸大小
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.addListener(WebAppRootListener.class);
        servletContext.setInitParameter("org.apache.tomcat.websocket.textBufferSize","128000");
        servletContext.setInitParameter("org.apache.tomcat.websocket.binaryBufferSize","128000");
    }
} 

和客戶端連接建立后,配置空閑超時時間

session.setMaxIdleTimeout(10000);  

再重新測試,系統的容量提高了很多(雖然無法完全避免OOM)

 

參考:https://www.cnblogs.com/qiantao/p/13576441.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM