問題:
高并發(fā)大壓力下發(fā)現(xiàn)TOP平臺消息會出現(xiàn)消息串掉,
先說一下具體的原因:
數(shù)據(jù)交互中,其中一方單獨認為業(yè)務交互失敗,邏輯回收而非物理關閉復用的信道,另一方在完成業(yè)務操作時將業(yè)務數(shù)據(jù)再次推送到已經(jīng)被邏輯回收的通道上,會導致請求和相應錯位。
代碼層設計問題:
1. 信道一次業(yè)務交互中的多次消息交互缺少唯一的會話碼,導致中間任何一次交互出現(xiàn)問題,后續(xù)的數(shù)據(jù)會錯位到后續(xù)復用此信道其他請求中。
2. 底層信道的回收,異常處理,沒有在信道層直接處理,而是將錯誤通過業(yè)務堆棧拋到最外層ajp協(xié)議解析線程管理池去做,導致不論是業(yè)務捕獲異常或者是servlet,spring框架捕獲異常都會出現(xiàn)串號。
解決方法:
1. 在協(xié)議層增加會話碼,發(fā)現(xiàn)會話錯位,關閉信道。
2. 讓底層信道出現(xiàn)異常自己回收和關閉信道,連接池獲取連接的時候判斷連接是否已經(jīng)無效,無效即刻移除。(不需要用拋錯誤堆棧的方式來實現(xiàn))
后續(xù):
TOP這邊已經(jīng)在考慮異步Web request請求處理的方式,后續(xù)在安全的要求下可以和nginx 做類似信道復用的web服務器+應用服務器的模式。
詳細說明看下面的內(nèi)容:
用兩張圖片說明問題。
第一張是一次請求在JK和Jboss-web之間的交互過程。

問題發(fā)生在第四步,在jboss-web向JK請求body的數(shù)據(jù)的時候可能產(chǎn)生超時或者其他IO異常,這時候直接會走到9這步,由于異常被捕獲,連接將不會被物理關閉。

一次請求處理的調(diào)用順序如上,按照數(shù)字順序,當在5出現(xiàn)問題的時候,AjpAprProcessor沒有自己物理關閉,而是依賴異常上拋的方式,返回到ajpAprProtocal來關閉AjpAprProcessor。簡單來做就只需要在5就地處理,關閉連接,雖然會被放入連接池,但是只要在2這個步驟使用連接池的時候檢查一下連接狀態(tài)就可以丟棄這些無效的連接。