Rust:调查一个奇怪的内存溢出错误

主要观点:

  • Qovery 有个叫 engine-gateway 的小服务,负责与客户端部署者的连接和数据传输,内存占用低,主要负责认证授权和将字节流转发到数据存储进行处理。
  • 该服务在生产环境中运行数月无干预,内存使用<50Mib,但某天突然重启并被警报,服务仪表盘显示崩溃前各项资源正常,且应用日志无异常,该服务运行在 Kubernetes 上,最后重启原因是内存溢出(OOM)。
  • 深入调查发现 dmesg 命令显示是 tokio-runtime-w 触发了 OOM 杀手,内存使用情况显示 engine-gateway 进程使用过多内存,且是匿名页内存分配导致,监控频率为 10 秒,内存激增太快导致进程被瞬间杀死。
  • 虽将服务内存限制翻倍但仍出现 OOM 并导致服务中断,后改用 jemalloc 进行内存分配分析,发现是调用 anyhow::Error 的 Debug 实现触发了回溯符号化并缓存,导致 OOM,而修改代码为使用 Display 实现则可避免该问题,最后通过设置环境变量 RUST_LIB_BACKTRACE=0 解决该问题。

关键信息:

  • engine-gateway 服务的作用和特点。
  • 服务突然重启及 OOM 的情况和排查过程。
  • 深入调查中发现的与内存分配和 anyhow 库相关的问题及解决办法。

重要细节:

  • 服务运行的环境(Kubernetes)及相关状态信息。
  • 各种堆栈跟踪、内存统计等细节信息。
  • anyhow 库在不同环境变量设置下的行为及导致 OOM 的具体代码路径。
阅读 7
0 条评论