OpenResty XRay 分析和解决 B 站重大线上事故
摘要: OpenResty Inc. 团队利用商业产品 OpenResty XRay 的动态追踪技术,在介入 B 站《2021.07.13 我们是这样崩的》文中所描述的重大线上事故后很短的时间内定位了导致 B 站线上服务不可用的问题根源,并帮助解决重大线上事故。
B 站(Bilibili.com)这两天发表了一篇总结去年那场大事故的文章《2021.07.13 我们是这样崩的》。文章发出后引发了广泛的关注和讨论,有不少关注 OpenResty 的朋友也因此联系到我想要了解更多的细节。所以我希望通过这篇文章,从 OpenResty 的角度还原此事件的解决过程,同更多感兴趣的技术伙伴介绍我们所运用的技术手段和工具。
从前我们专注于产品和技术研发,较少与外界介绍我们的技术和产品。这篇文章也是我们一系列分享的开端,让更多的企业知道我们的 OpenResty XRay 产品和服务,从而帮助更多企业发现和快速解决各种线上问题。
事故描述
背景:B 站基于开源 OpenResty 开发了他们的内部网关系统。
事故现场:B 站当时所有线上服务器的 OpenResty 进程总是占用 CPU 100%,但不能处理任何请求。重启无法恢复,回滚他们最近的业务代码变更也无法恢复。所有服务器都有这个问题。
B 站是我们的 OpenResty XRay 产品的商业客户。OpenResty XRay 是一款基于动态追踪技术的系统故障排查和性能优化软件。事故发生一段时间后,B 站的运维团队联系到我们,希望我们能帮助分析线上的一个严重问题。
事故分析过程
我们首先通过线上由 OpenResty XRay 产品自动采样的 C 语言级别 CPU 火焰图,确定了他们的 OpenResty 的 nginx 进程的几乎所有 CPU 时间都花费在执行 Lua 代码上面。
出于对客户的隐私保护和数据安全,这张图里只显示了 OpenResty 开源软件里的函数帧,隐去了 B 站自己的 Lua 代码相关的信息。
然后我们再通过 OpenResty XRay 自动采样的 Lua 语言级别的 CPU 火焰图确认了几乎所有的 CPU 时间都花费在了单条 Lua 代码路径上。看起来是那条 Lua 代码路径发生了死循环。我们的 Lua CPU 火焰图定位的 Lua 代码路径可以精确到代码行级别。
同样的,我们只保留了不敏感的开源代码的函数帧。
B 站原文中提到的 Lua 火焰图就是 OpenResty XRay 在 B 站生产服务器上采样有问题的 OpenResty 服务进程得到的。
OpenResty XRay 在 B 站线上生成火焰图也就花费了几十秒到几分钟的时间,因为使用 100% 非侵入的动态追踪技术,整个过程不需要对 B 站的进程和应用进行任何修改。
根据 Lua 火焰图最终确认根源问题是 B 站的业务往配置元数据写入了个字符串类型的权重 0 值的坏数据(即 “0”),而 OpenResty 的 lua-resty-balancer 库的 Lua API 期望的是数值类型的权重值,从而导致了无限递归和无限循环。
LuaJIT 的即时( JIT)编译器在这里并没有 bug。之所以最初怀疑是 JIT 编译器的问题是因为对应的 Lua 代码路径乍一看并没有任何问题,同时 B 站另一个业务团队未告知的操作也对线上服务产生了影响。字符串 0 和数值 0 的区别是非常微妙的。最终我们排除了 JIT 编译器的 bug 可能性,确定了字符串 0 这个问题根源。
事故后续修复和加固
B 站在业务层面确保不会再有字符串类型的上游服务器的权重值被写入配置数据。
OpenResty XRay 新版也提供了打印 Lua 调用栈上所有局部变量的值的新功能,可以让类似问题被更快更直接地定位。
我们事后也对开源 OpenResty 的 lua-resty-balancer 库针对这种 API 误用进行特别加固,确保任何误传的字符串类型的权重值总是会被强制转成数值类型。
OpenResty XRay 产品和服务
OpenResty XRay 是由 OpenResty Inc. 公司提供的一款非侵入式的在线软件分析系统,基于由 OpenResty Inc. 团队显著增强过的动态追踪技术。目前可以自动针对 OpenResty、Nginx、LuaJIT、PHP、Python、Perl、Go、PostgreSQL、Redis 等各种不同的开源软件以及运行在这些开源软件之上的客户业务代码进行深入的分析和监控。未来我们还会陆续加入对更多技术栈的支持,包括Java, Ruby等。用户使用 OpenResty XRay,可以快速发现和精准定位各种性能问题、功能问题和安全问题, 从而保证应用的稳定性。
OpenResty XRay 的精准定位和问题排查无需对客户应用作任何修改,无需加装任何特殊插件、模块或编译选项,也不会向客户进程空间注入任何代码。同时也可以穿透客户现有的未经修改过的 Docker 或 Kubernetes(K8s)容器,透明地分析容器内的各种应用。
除了 B 站,OpenResty XRay 也曾经成功地帮助 Zoom、微软、去哪儿网等很多公司在线上定位和优化了很多真实的线上问题,从高 CPU 波峰到高内存使用,再到内存泄漏、异常的请求延时、高硬盘 IO 等各种问题。
OpenResty XRay 也支持自动对很多问题进行追踪和分析推理,直至定位问题根源。
结语
事故最终得到完美的解决,感谢 Bilibili.com 对我们公司产品和技术的信任和支持!感兴趣的同学可以通过 OpenResty XRay 产品主页 了解OpenResty XRay的更多信息并申请试用。
OpenResty XRay 中使用的 Lua 语言级别的 CPU 火焰图工具在这里有中文教程介绍。OpenResty XRay 使用的是增强过的私有动态追踪技术,感兴趣的同学可以参考我年初时写的这个系列文章:《Ylang: Universal Language for eBPF, Stap+, GDB, and More》。
关于作者
章亦春是开源 OpenResty® 项目创始人兼 OpenResty Inc. 公司 CEO 和创始人。
章亦春(Github ID: agentzh),生于中国江苏,现定居美国湾区。他是中国早期开源技术和文化的倡导者和领军人物,曾供职于多家国际知名的高科技企业,如 Cloudflare、雅虎、阿里巴巴, 是 “边缘计算“、”动态追踪 “和 “机器编程 “的先驱,拥有超过 22 年的编程及 16 年的开源经验。作为拥有超过 4000 万全球域名用户的开源项目的领导者。他基于其 OpenResty® 开源项目打造的高科技企业 OpenResty Inc. 位于美国硅谷中心。其主打的两个产品 OpenResty XRay(利用动态追踪技术的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最适合微服务和分布式流量的全能型网关软件),广受全球众多上市及大型企业青睐。在 OpenResty 以外,章亦春为多个开源项目贡献了累计超过百万行代码,其中包括,Linux 内核、Nginx、LuaJIT、GDB、SystemTap、LLVM、Perl 等,并编写过 60 多个开源软件库。
关注我们
如果您喜欢本文,欢迎关注我们 OpenResty Inc. 公司的博客网站 。
我们也在 B 站上也有 OpenResty 官方的视频分享空间,欢迎订阅。
同时欢迎扫码关注我们的微信公众号: