bigywater.tech
Rust · 141

Tokio TCP Echo Server

异步服务器真正的优势是什么?这篇写一个最小的 tokio 回显服务,在同一台机器上与「每连接一线程」对比三个数字:能撑多少连接、占多少线程与内存、单连接的延迟。

5 个线程
tokio 服务端保持 3000 个连接时的进程线程数
1507 个连接
线程版服务端在尝试 3000 个连接时失败的位置
22.9 对 20.3 µs
单连接回显往返:tokio 对线程

最小的回显服务

实测 · 本机执行输出
    服务端:一个连接结束,共回显 5 字节(对端 IP 127.0.0.1)
  客户端:发 "hello" 收 "hello"
    服务端:一个连接结束,共回显 10 字节(对端 IP 127.0.0.1)
  客户端:发 "tokio echo" 收 "tokio echo"

阻塞式 TCP 与线程版见TCP Listener 与 TcpStream;非阻塞与 poll 见非阻塞 IO。tokio 1.x 从 crates.io 下载。

tokio 保持 3000 个连接

实测 · 本机执行输出
    tokio:建立并保持 3000 个连接用时 162 ms;其中 1000 个各做一次回显往返用时 7 ms,1000 个正确
    线程数 5 → 5(tokio 工作线程 + 主线程等),RSS 2 MB → 5 MB

每连接一线程

实测 · 本机执行输出
    线程服务:建立 1507 个连接用时 393 ms,第 1507 个失败:Connection reset by peer (os error 54)
    线程数 1 → 1509,RSS 2 MB → 29 MB

线程数与 RSS 通过 ps 读取;失败位置与系统限制有关,换机器会不同。

单连接的延迟

实测 · 本机执行输出
    tokio 服务端  平均往返 22.9 µs
    线程服务端      平均往返 20.3 µs

异步运行时的调度见Tokio 任务调度。

分步演示

Tokio TCP Echo
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。macOS;tokio 1.x
    • 没有验证:更大的连接数(几万)、写入慢的客户端造成的背压、优雅关闭、每个连接的任务内存占用、tokio::net::TcpStream 与 into_split 的所有权、TLS、Linux 上线程数上限的位置
    京ICP备2026067502号-1京公网安备11010502063487号