『調錯』大半夜調試TCP延遲問題

背景

公司有個項目,需要一個高可用緩存服務。
之前通訊技術選型時,測試過 UDP TCP HTTP QUIC gRPC 性能。

初步結論:
1、UDP 很快,CPU 很低,但無法超過 64K (大於12K 甚至都開始內網丟包)

2、HTTP 傳統的 WebApi (中規中矩的技術選型,延遲都還好,但真想完善還得每次增加 WebApi 安全驗證 —— 就開始損失性能了)

3、傳說中的 Quic,說是用UDP實現了一套類似 TCP 的重發機制(實測 CPU 增加,吞吐降低 —— 真就和本機TCP一樣了)

4、本來自己心目中最想用的是 TCP(有一套成熟的TCP庫,實戰從未失望),只需建立連接時只需一次安全驗證(目前很多數據庫、Redis、MQTT、RabbtMQ 底層都是TCP,也都是連接時安全驗證)—— 但不知道爲啥,局域網跨機部署 一來一回一次交互 延遲達到到 100ms(經驗中:同步的 一來一回 TCP 本機可以達到 5000/s ~ 7000/s)。

TCP讓我很氣餒

印象中的 TCP:

  • 單核同步速度 5000/s ~ 7000/s
  • 四核異步速度 可以把CPU跑滿,30000/s 都只是小意思

但這次跨機部署,每次交互 100ms 延遲(摺合 10/s 的速度 —— 這還玩毛線)

雖然多核異步,依然能把帶寬跑滿,交互也能達到 30000/s 吞吐量 —— 但每次交互的延遲 100ms 就很不合適。

難道是我之前的項目,都只在乎吞吐量,卻沒有關注延遲的緣故 ?

TCP 減少延遲調優

優化前的現狀

本機交互 0ms,吞吐量 7000/s
image

虛擬機交互 85ms,吞吐量 20/s
image

虛擬機ping延遲 1ms —— ping 一來一回也就 1ms, 沒理由 TCP 一來一回 85ms 啊
image

使用異步代碼優化後(沒啥用)

本機交互 0ms,吞吐量 7000/s
image

虛擬機交互 85ms,吞吐量 20/s
image

會不會是 Linux 的問題?換成 Win10 和 Win10 交互還是鳥樣
image

找到關鍵優化代碼

虛擬機交互 0ms
image

最終吞吐量 800/s
image

至此,執念已消,總結:

最終優化後的代碼,依然選用回調異步
image

真正其決定性作用的參數是這個 NoDelay
image

TCP的 吞吐量 和 延遲 區別

  • 延遲,比如一個單車道,路面坑坑窪窪 一輛車一來一回 100秒,路面平整 一輛車一來一回 10秒 (這就是延遲)
  • 吞吐量,比如一個 100車道,雖然路面坑坑窪窪,延遲雖高,但吞吐量依然可以很大
  • 降低了延遲後,原本100個車道的吞吐量,只需要 10個車道即可
  • 本文只記錄了如何降低延遲,沒有測試多併發時的吞吐量 —— 不用測,30000/s + 一定是了

小INK
2023-03-30 01:17
晚安,各位。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章