去年这个时候,我们的核心服务还在用 Python 原型跑。一年后,它成为了处理百万级请求的 Rust 服务。这篇文章记录迁移过程里的关键决策、踩过的坑,以及那些“早知道就好了”的时刻。
为什么不是 Go?
团队里有人建议用 Go。确实,Go 的并发模型很吸引人,生态也成熟。但我们的场景有几个特殊之处:大量 CPU 密集型计算、对内存布局有精细控制的需求,以及未来可能需要与 C++ 库交互。
Rust 的零成本抽象和无运行时开销,在这个场景下成了决定性优势。
选择 Rust 不是因为它流行,而是因为它的约束恰好匹配了我们的需求。
第一阶段:影子模式
我们没有直接替换旧服务,而是让 Rust 服务以“影子模式”运行了两个月,接收同样的请求,但不返回给客户端,只记录响应差异。
- 浮点数精度差异导致的排序不一致
- JSON 序列化时 null 和缺失字段的处理差异
- 一个隐藏的竞态条件,在 Python 的 GIL 保护下从未触发
性能数据
P99 延迟: 45ms -> 12ms (-73%)
CPU 使用率: 68% -> 22% (-68%)
内存占用: 4.2GB -> 890MB (-79%)
下一步
目前服务已经稳定运行了四个月。下一步计划是引入 WASI 组件隔离第三方插件、探索 io_uring 在特定路径上的收益,以及把部分计算密集型任务 offload 到 GPU。
评论
评论默认审核后展示。你可以匿名留言,也可以登录后保留自己的互动记录。