『调错』大半夜调试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
晚安,各位。

posted on 2024-03-30 01:20  InkFx  阅读(34)  评论(0编辑  收藏  举报