Nginx worker 进程 CPU 占用不均——个别 worker 打满、其余接近空闲——往往是请求分配层面的问题,比如监听端口未启用 reuseport 选项。在这个真实客户案例中,OpenResty XRay 把一套 DNS 服务的 CPU 不均衡精确定位到了这一配置缺失,外加一个消耗 60% CPU 时间的 cjson_decode 热点,并在几分钟内将核心瓶颈的 CPU 消耗降低了 60% 以上。

下面按火焰图逐步展开整个定位过程。

症状:部分 Nginx Worker 进程 CPU 打满,其余接近空闲

客户运行的 DNS 服务系统面临严重的 CPU 使用率不均衡问题,部分 Nginx worker 进程 CPU 占用率过高,而其他进程相对空闲。同时,系统整体响应延迟增加,特别是在高负载情况下表现更为明显。这种不均衡不仅影响了服务的稳定性,还导致资源利用效率低下,增加了运营成本。

传统的性能分析方法难以精确定位根本原因,因为问题涉及多个层面的复杂交互。在这种情况下,客户请求 OpenResty XRay 团队支援,我们立即使用 OpenResty XRay 对系统进行了全方位的性能剖析。

OpenResty XRay 如何定位根因

通过 OpenResty XRay 分析器,我们对目标系统进行了深入分析,发现了以下关键问题:

未启用 reuseport:请求分配为何不均

首先,我们检查了 Nginx 的配置状态:

use_accept_mutex: 0
listening on: 0.0.0.0:8090, reuseport: 0
listening on: 0.0.0.0:3581, reuseport: 0
listening on: 0.0.0.0:8081, reuseport: 0
listening on: 0.0.0.0:8088, reuseport: 0
listening on: 0.0.0.0:11080, reuseport: 0
listening on: 0.0.0.0:8080, reuseport: 0
listening on: 0.0.0.0:9000, reuseport: 0
listening on: 0.0.0.0:9090, reuseport: 0
listening on: 0.0.0.0:1935, reuseport: 0
listening on: 0.0.0.0:80, reuseport: 0

发现所有监听端口都未启用 reuseport 选项,导致请求分配不均。

火焰图显示 cjson_decode 消耗了 60% 的 CPU 时间

通过 C 火焰图分析,我们发现约 60% 的 CPU 时间消耗在 cjson 模块上。

C 级 CPU 火焰图:Nginx DNS 服务中 cjson.so 相关帧(luaopen_cjson)被标出,是最主要的 CPU 消耗点

从 Lua 火焰图看,约 60% 时间消耗在 cjson_decode 操作,约 30% 时间消耗在 shcache.lua:load,仅约 5% 时间消耗在核心业务逻辑 dns_server.lua 中。

Lua 级 CPU 火焰图:cjson_decode 约占 60% CPU 时间,shcache.lua load 约占 30%,dns_server.lua 业务逻辑仅占极小部分

这表明 JSON 解析成为了绝对的性能瓶颈——与我们在这个 JSON 解析内存案例中诊断过的属于同一类问题。

旧版 LuaJIT 带来的 Cosocket 接收开销

另一个显著的 CPU 消耗点是 cosocket 接收操作,占用了约 16% 的 CPU 时间:

ngx_stream_lua_socket_tcp_receive
  -> ngx_stream_lua_socket_tcp_receive_retval_handler
  -> ngx_stream_lua_socket_push_input_data
  -> luaL_addlstring [/etc/nginx/luajit/lib/libluajit-5.1.so.2.1.0]

分析显示客户使用的是较老版本的 LuaJIT,而最新版已对此进行了优化。

修复:三项优化与各自的实测收益

基于 OpenResty XRay 的深度分析结果,我们的技术团队为客户制定了针对性的优化方案:

拉平 Worker 进程间的负载分配(提升 20–30%)

通过配置调优解决了 worker 进程间负载不均的问题,显著改善了系统资源利用效率,整体性能提升 20-30%。

削减 JSON 解析瓶颈 60% 以上的 CPU 消耗

针对识别出的 JSON 处理性能瓶颈,我们提供了多层次的优化策略:

  • 数据处理流程重构,减少不必要的计算开销
  • 智能缓存机制设计,大幅降低重复操作成本
  • 配置管理优化,提升系统响应效率

通过这些优化,核心瓶颈的 CPU 消耗降低了 60% 以上,系统吞吐量获得显著提升。

升级运行时技术栈(额外提升 5–10%)

基于版本兼容性分析,我们为客户规划了技术栈升级路径,进一步优化底层组件性能,额外获得 5-10% 的性能提升。

这个案例展示了 OpenResty XRay 在复杂性能问题诊断中的强大能力,能够精确定位到代码级别的性能瓶颈,为优化提供明确方向。

总结:OpenResty XRay 几分钟内的发现

  • 火速精准定位全部性能瓶颈
  • 深入到代码级别,发现传统监控根本看不到的问题
  • 核心 CPU 占用降低超过 60%,系统整体性能提升 20%~30%
  • 找出 JSON 解析高达 60% 的 CPU 消耗,直击性能瓶颈
  • 发现 worker 配置严重失衡,负载分配极不合理
  • 排查出老旧组件拖累整体性能,及时升级调整
  • 运维效率大幅提升,为客户节省了可观的人力和成本投入
  • 全程使用火焰图可视化,性能问题一目了然,优化方向清晰可量化

在今天这个系统架构复杂、业务高并发的时代,性能问题往往不是表面现象,靠传统监控很难找出真正的根源。OpenResty XRay 作为业界领先的动态追踪平台,能帮技术团队快速深入到问题核心,制定精准、可落地的优化方案。

如果您也想让系统跑得更稳、更快、更节省。或者希望提前进行一次深度性能优化体验,欢迎申请产品试用。让 OpenResty XRay 成为你团队手里最值得信赖的利器。

常见问题

为什么个别 Nginx worker 进程的 CPU 占用远高于其他进程?

在本案例中,所有监听端口都未启用 reuseport 选项,请求无法均匀分配到各个 Nginx worker 进程——部分 worker 占用率过高,其余相对空闲。对负载分配相关配置调优后,资源利用效率明显改善,整体性能提升 20–30%。

如何找出 Nginx / OpenResty Lua 代码中的 CPU 消耗点?

用两个层级的火焰图逐层收窄。本案例中,OpenResty XRay 的 C 级火焰图显示约 60% 的 CPU 时间在 cjson 模块内;Lua 级火焰图进一步定位到 cjson_decode 约占 60%、shcache.lua:load 约占 30%,而核心业务逻辑 dns_server.lua 仅约 5%。

cjson_decode 为什么会消耗 60% 的 CPU 时间?

该服务在数据处理路径上反复承担 JSON 解析的开销,使 cjson_decode 成为最大的单一 CPU 消耗点。通过重构数据处理流程、并设计智能缓存机制降低重复操作成本,核心瓶颈的 CPU 消耗降低了 60% 以上。

关于 OpenResty XRay

OpenResty XRay 是一款动态追踪产品,它可以自动分析运行中的应用,以解决性能问题、行为问题和安全漏洞,并提供可行的建议。在底层实现上,OpenResty XRay 由我们的 Y 语言驱动,可以在不同环境下支持多种不同的运行时,如 Stap+、eBPF+、GDB 和 ODB。

关于作者

章亦春是开源 OpenResty® 项目创始人兼 OpenResty Inc. 公司 CEO 和创始人。

章亦春(Github ID: agentzh),生于中国江苏,现定居美国湾区。他是中国早期开源技术和文化的倡导者和领军人物,曾供职于多家国际知名的高科技企业,如 Cloudflare、雅虎、阿里巴巴, 是 “边缘计算“、”动态追踪 “和 “机器编程 “的先驱,拥有超过 22 年的编程及 16 年的开源经验。作为拥有超过 4000 万全球域名用户的开源项目的领导者。他基于其 OpenResty® 开源项目打造的高科技企业 OpenResty Inc. 位于美国硅谷中心。其主打的两个产品 OpenResty XRay(利用动态追踪技术的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最适合微服务和分布式流量的全能型网关软件),广受全球众多上市及大型企业青睐。在 OpenResty 以外,章亦春为多个开源项目贡献了累计超过百万行代码,其中包括,Linux 内核、Nginx、LuaJITGDBSystemTapLLVM、Perl 等,并编写过 60 多个开源软件库。

关注我们

如果您喜欢本文,欢迎关注我们 OpenResty Inc. 公司的博客网站 。也欢迎扫码关注我们的微信公众号:

我们的微信公众号

翻译

我们提供了英文版原文和中译版(本文)。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!