TCP ACK 延遲40ms

不論宣稱如何完美的解決方案,都會引入另外一個更復雜的問題。

1、背景

我負責的緩存系統有一個版本號模塊,專門用來對數據生成惟一的版本號seq來保證數據的惟一性,從而作到數據數據實時更新以及避免舊數據覆蓋新數據的問題。 
這個模塊是其餘人交接給個人,以前服務一直都正常,也就沒去細看。
最近訪問量愈來愈大了,服務出現一些失敗,因此須要先梳理整個模塊的狀況,而後在從總體上來優化這個模塊。算法

2、高延時

版本號模塊一梳理沒關係,發現一大堆問題,如未來處理數據存在瓶頸、模塊不可擴容、存在同步邏輯等等。 
其中一個問題就是拉取版本號時,平均延時比較高。 
看上圖,能夠發現,測試環境平均耗時只有1毫秒,而正式環境是20多毫秒。這個不該該這麼高的。緩存

那版本號服務的延時爲何這麼高呢? 
目前我只能說不知道。 
上面那個監控也是那個服務交接過來後,在我給那個服務增長功能時增長的。 
而對於版本號模塊交接過來後發現沒監控,可是加監控這種優先級最低的事情是不會單獨去作的,除非出了問題,好比如今,不得不加了。服務器

如今能作的是先tcpdump抓個包看看,結果發現一個奇怪的現象,是的,就是這篇文章的標題,某些ACK延遲了40ms才發出來(固然,監控的高延時不是這個致使的)。微信

3、延遲ACK

如上圖,能夠看到某些時候,服務端回數據包了,可是客戶端卻遲遲沒有回覆ACK,直到40毫秒以後才發出ACK。網絡

爲何會這樣呢? 
查了TCP相關的資料,瞭解到TCP的 Nagel算法算法在某些時候,會進入這樣一個延遲迴復ACK的邏輯,而後等待40毫秒,觸發超時邏輯,最終回覆了ACK。tcp

這對應了個人其中一個座右銘:不論宣稱如何完美的解決方案,都會引入另外一個更復雜的問題測試

4、爲何延遲

對於後臺服務,通常都是長鏈接,並且是一發一收的模式。
場景就像下面的樣子。優化

 
  1. CLIENT -> SERVER:發送請求數據  spa

  2. SERVER -> CLIENT:迴應收到數據了  3d

  3. SERVER -> CLIENT:返回處理後的數據  

  4. CLIENT -> SERVER:迴應收到數據了  

是否是發現服務器連續想客戶端發了兩次數據,一次是會請求數據的ACK,一次是請求數據的結果。
這兩次回包若是可以合併爲一次,網絡上的包是否是一下就少了四分之一。
說幹就幹,TCP的Nagel加了這樣一個功能,先探測通訊模型是否是一發一收的,符合條件了收到請求數據包時就先不回ACK,等一會,而後帶着處理後的數據一塊兒回ACK,俗稱延遲ACK。

那天然就會面臨一個問題:若是沒有下個請求了,這個ACK就遲遲的發不會去了嗎? 
因此這個延遲功能就須要加個兜底時間,超過了兜底時間就補上遲遲沒發的ACK。

那怎麼手動關閉這個功能呢?
root權限下把/proc/sys/net/ipv4/tcp_no_delay_ack文件的值修改爲1便可。 
這樣的問題就是每一個TCP數據包都會有一個ACK包,增長了網絡的包量。

本文首發於公衆號:天空的代碼世界,微信號:tiankonguse-code。

推薦閱讀:

經濟危機(一)

《長尾理論》解釋了抖音爲啥火了

數據髒了怎麼辦

讀恐怖小說《1984》

中年危機筆記與思考

靜態庫遇到靜態庫

 

❖ 歡 迎 分 享 到 朋 友 圈 哦 ❖

 

相關文章
相關標籤/搜索