天天看點

websocket多線程問題

springMVC

tomcat8

後端建立websocket 前端連接配接上來,背景會主動推送agent腳本執行資訊,由于采用netty架構,保證并發性,執行的結果是多線程處理的,通過websocket傳回前端居然報錯了,很是費解。症狀見下圖。

websocket多線程問題
websocket多線程問題

從圖中可以看出,遠端處于【TEXT_PARTIAL_WRITING】狀态,就這這個關鍵字google(不得不說就英文搜尋而言,google強太多),

最後發現,tomcat的websocket沒有相關的多線程處理,有人在apache上提bug,可以看一下開發者給的回複:

tomcat8 websocker bug

一個簡單的聊天應用程式與3個使用者聊天将導緻并發調用Async.sendText()當A和B都發送一個必須傳遞到C的消息,是以用例是很常見的。

應用程式擔心同步或排隊并發調用Async.sendText()會對執行并發寫入的應用程式造成巨大的負擔,我相信這不是JSR 356的意圖(盡管規範并沒有說明并發保證) 。

javaDoc,RemoteEndpoint.Basic明确指出不允許并發發送消息,但是RemoteEndpoint.Async沒有,并且websocket eg 的意圖是不允許并發,最終結論将此bug定位為無效bug

看下面的評論也是很有意思,哈哈,大部分人認為容器應該為應用程式開發者提供便利,提供容器内部的緩沖,,而不是程式開發者自己管理websocket Session緩沖區。有一個方法是利用同步來降低這種問題的出現頻率,與此同時,Tyrus 1.5是安全的,貌似隻有tomcat存在這個問題。

采用同步操作之後,由于agent會有很多中間結果,當第一條消息到來把鎖搶占之後,後面的結果已經到來,當鎖釋放之後,其他線程搶占鎖,尼瑪,原先有時間順序的結果變得混亂無序. 難道真的要自己實作一套緩沖隊列嗎。左思右想,最終決定還是有公平鎖好了

公平鎖是個好東西,自己内部實作了一套等待隊列,雖然效率有點低,但是對業務來說可以滿足需求

websocket多線程問題

本文轉自lzwxx 51CTO部落格,原文連結:http://blog.51cto.com/13064681/1943441