打造极速 Tokio 应用的实战原则
Principles for Fast Tokio Applications

刚从 RustConf 回来,我和社区深入探讨了异步应用的调试与基准测试。在 Tokio 运行时上,性能往往取决于公平性与批处理的微妙平衡。我发现,许多所谓的性能问题其实源于应用代码本身,而非 Tokio。文章分享了关键原则:为降低延迟需频繁让出控制权,为提升吞吐量则应批量处理工作。同时,要警惕全局资源竞争、互斥锁导致的运行时停滞,并合理限制并发度。通过将 Tokio 工作线程与其他线程隔离,往往能显著改善 P99 延迟。这些经验旨在帮助你构建更高效的异步系统。
编写异步应用以获得良好性能,是在公平性与批处理、竞争与隔离之间寻求平衡的艺术。
HN 评论区
62- saghm
"小心使用互斥锁"是个好建议,但我有点惊讶的是,它没有明确点出 Tokio 提供的各种通道(channel)作为替代方案(详情见:https://docs.rs/tokio/latest/tokio/sync/index.html)。这里有多种选项适用于不同的使用场景,甚至不需要启用 runtime 功能就能使用它们(例如,如果你只想做一次完成检查而不是 await)。我估计,在使用 Tokio 时遇到的互斥锁瓶颈中,至少有半数本可以通过完全不使用互斥锁,而是通过某种通道将真正需要的数据传递给不同任务来避免。
另一个我偶尔用过的小技巧有点取巧,但确实能解决问题:当只需要在互斥锁保护下读取数据快照,而不需要阻止其他修改时,你可以直接克隆数据然后释放互斥锁,让其他操作继续执行,代价是数据可能稍显陈旧。
- 5ersi
若要追求真正的极致性能,你应该使用线程自旋(busy-spinning)、CPU 绑定以及 SPSC/MPSC 环形缓冲区。
- dist1ll
当你开始着手优化 Tokio 时,不妨看看 ef_vi/DPDK + SPDK。
- Tsarp
智能体编码(agentic coding)的一个绝佳用途,就是能够添加非常细粒度的追踪(tracing)探针,从而助力这类优化工作。
- jeffbee
我在业界遇到的所有重要服务器应用都遭遇了同样的问题,这让它们的作者感到惊讶,但在我看来却显而易见:应用将大部分 CPU 时间都耗费在了元操作上,比如进出 epoll、从自身窃取任务等等。编写 Tokio 服务器确实有一些原则,原文提到的这些点很好,但我认为它们鲜为人知,而且太容易被人违背了。