問題:
高并發大壓力下發現TOP平臺消息會出現消息串掉,
先說一下具體的原因:
數據交互中,其中一方單獨認為業務交互失敗,邏輯回收而非物理關閉復用的信道,另一方在完成業務操作時將業務數據再次推送到已經被邏輯回收的通道上,會導致請求和相應錯位。
代碼層設計問題:
1. 信道一次業務交互中的多次消息交互缺少唯一的會話碼,導致中間任何一次交互出現問題,后續的數據會錯位到后續復用此信道其他請求中。
2. 底層信道的回收,異常處理,沒有在信道層直接處理,而是將錯誤通過業務堆棧拋到最外層ajp協議解析線程管理池去做,導致不論是業務捕獲異?;蛘呤莝ervlet,spring框架捕獲異常都會出現串號。
解決方法:
1. 在協議層增加會話碼,發現會話錯位,關閉信道。
2. 讓底層信道出現異常自己回收和關閉信道,連接池獲取連接的時候判斷連接是否已經無效,無效即刻移除。(不需要用拋錯誤堆棧的方式來實現)
后續:
TOP這邊已經在考慮異步Web request請求處理的方式,后續在安全的要求下可以和nginx 做類似信道復用的web服務器+應用服務器的模式。
詳細說明看下面的內容:
用兩張圖片說明問題。
第一張是一次請求在JK和Jboss-web之間的交互過程。
問題發生在第四步,在jboss-web向JK請求body的數據的時候可能產生超時或者其他IO異常,這時候直接會走到9這步,由于異常被捕獲,連接將不會被物理關閉。
一次請求處理的調用順序如上,按照數字順序,當在5出現問題的時候,AjpAprProcessor沒有自己物理關閉,而是依賴異常上拋的方式,返回到ajpAprProtocal來關閉AjpAprProcessor。簡單來做就只需要在5就地處理,關閉連接,雖然會被放入連接池,但是只要在2這個步驟使用連接池的時候檢查一下連接狀態就可以丟棄這些無效的連接。