一不小心,陷入TCP的性能問題


一、現象

  在一次訪問請求nginx中,通常只需要幾毫秒的RT,但當請求數據達到某一個數值時,rt明顯提高,甚至超過了300毫秒。 

二、問題的原因

  大家都知道,TCP為了提高帶寬利用率和吞吐量,做了各種優化。比如delay ack和Nagle算法。就是這樣的一些優化使用不慎,導致陷入性能問題。接下來就先分別說說delay ack和Nagle算法。

  • 什么是delay ack

  就以我們的Nginx為例吧。nginx收到請求后,立即返回一個ack收到確認包。這個包沒有只有消息頭沒有任何數據內容。這就導致一個明顯的問題:帶寬利用率比較低效。那有沒有辦法可以優化呢?有,就是delay ack。怎么做呢?就是Nginx收到數據不要着急發送ack包,而是等一段時間比如40毫秒,如果這40毫秒內有數據要發送給client。那么這個ack就可以打這趟順風車了,從而節省資源。如果40毫秒內沒數據發送給client呢,沒辦法,到了40毫秒也必須發送ack包。因為client以為丟包重傳的代價更大。

  還有一種情況就是,nginx收到數據在延緩等待發送ack包時,又收到client的一個數據包。這時nginx會把兩個ack包合並為一個ack包回復給client。

  • 什么是Nagle算法

  在發送數據包時,如果數據包小於MSS(最大分段大小),則會去判斷是否有已發出去的包還沒有ack,如果有則不着急發送,等等前面的包收到回復再發送。

  • 性能問題關鍵點,client端啟動Nagle,server端啟動delay ack

  假如client發送一個http請求個server。這個請求時1600byte,MSS是1460byte。那么就會分成兩個tcp包,第一個1460byte,剩下的140byte放在第二個包。第一個包發送到server時,由於server開啟了delay ack,所以沒有立即ack,又因為server沒有收到完整的http請求包,所以也沒有立即進行http response,這就導致ack會一直等到40毫秒的delay時間。其實如果client立即發送第二個包,server收到后立即做出http response也不會有問題。問題時client啟動了Nagle算法,第一個包沒有收到ack,第二個包就不會立即發送出去。兩邊相互等。這就是性能問題的核心原因。

 


免責聲明!

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



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