.netcore使用SocketAsyncEventArgs Pool需要注意!


在.net中做網絡通訊往往都會用到SocketAsyncEventArgs,為了得到更好的性能配合Pool復用SocketAsyncEventArgs可以得到一個更好的效果,但在dotnet core在linux下這一塊的處理好像存在嚴重的問題!經過多天的測試,終於在Linux下Debug到這一情況,實時調試輸出接收的數據並不是當前請求的數據,而是之前另一請求的數據…… 接下來一下問題的實際情況!

問題的初現

前段時間有一個用戶說FastHttpApi跑了一段時間后就出現請求混亂的情況,用戶反映測試都正常,一發布上線在集群環境下運行一段時間后就會出現這情況……然后自己也根據相應的集群情況搭了個測試環境壓測了一段時間也沒出現這情況。本以為是用戶集群路由轉發的一些特性引起的異常就放下了這問題繼續完成新功能版本。

再次發現問題並確認

當組件的接口集群調用體功能完成后,開始做接口混合調用並發測試,這個時候出現一些怪異的情況,當前請求返回的數據並不是當前請求數據內容,而是來源於其他請求的數據內容!后來在測試的過程中同時用瀏覽器訪問相關接口,這個時候問題再一次出現,瀏覽器得到響應的數據並不是請求響應的數據,而是測試接口那邊的數據。后來關閉壓力測試,單獨用瀏覽器訪問還是有異常,打開日志發現瀏覽器請求的數據到服務端接收得到的數據竟然是之前測試請求的數據!這樣的問題相當尷尬……因為接收數據是由‘’SocketAsyncEventArgs‘’來處理,我一直不相信問題出在SocketAsyncEventArgs身上;最終迫於沒辦法的情況只能調試Linux運行的代碼,通過VS2017調試linux下dotnet core程序 最后把所有涉及請求的測試都關閉,單獨由瀏覽器請求,這個時候得到的請求我都感到驚訝! 

從結果看接收的數據並不是瀏覽器發出請求的數據,而是之前測試程序請求的內容,數據顯示User-Agent都不是瀏覽器的內容。

調整實現

按理這樣的問題不應該出現,因為早期MSDN也是推薦使用SocketAsyncEventArgs Pool的方式來復用SocketAsyncEventArgs提高性能。asp.net core核心的網絡模塊也是用這個的,如果有問題應該早就發現並解決掉!查看KestrelHttpServer 代碼后才發現並沒有使用SocketAsyncEventArgs Pool,每個連接都是單獨的SocketAsyncEventArgs 並沒有通過Pool共享,對應用的一次綁定的Buffer已經改由Pipe統一管理,每次收發都重新設置一下Buffer屬性。 為了快速地解決這一問題,放棄了原有SocketAsyncEventArgs Pool的使用方式,改用KestrelHttpServer方式進行組件改造,這種方式通過了兩天的混合並發測試暫沒有出現之前的情況,估計之前的問題是由SocketAsyncEventArgs共享復用導致的;則於無法判斷最終向corefx團隊提了:issue,https://github.com/dotnet/corefx/issues/33794 這問題應該是存在的,因為碰到這一情況還有其他人。

總結

這問題發現到排查花了一個多星期的時間……到底是SocketAsyncEventArgs 的bug還是使用上不對導致的還沒搞清楚,已經把相關問題描述和測試出現問題的程序提交給corefx團隊,希望盡快能搞清楚具體原因。通過這一次問題總結出一個問題,在做網絡測試的時候需要做更多的混合驗證測試,特別針對這一問題,由於數據都是符合當前協議的,所以並不會有什么異常出現。但導致數據混亂這種問題比異常來得更嚴重和影響面更大。


免責聲明!

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



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