一个旅游行业的客户发现,一些 web API 请求莫名其妙地多出了 200ms 的延迟。OpenResty XRay 只在慢速 TCP 连接上进行针对性抓包——不改动任何代码,也不影响生产环境的性能——最终将 Nginx 读取请求体的延迟定位到客户端本身:他们的安卓应用故意在发送请求头之后延迟 200ms 才发送请求体。

下面我们将完整回顾这次分析过程,演示 OpenResty XRay 如何使用“智能抓包”功能自动抓取慢速的(或有其他错误的)TCP 连接上的数据包。

问题

应用服务器原本应该处理得很快的一些 API 请求却耗时长达 200ms。

长延迟问题可能有很多不同的原因,比如磁盘 I/O 速度慢、内核网络堆栈或其他网络设备的数据包丢失、CPU 使用率高导致应用程序或 web 服务器响应速度减慢,或者只是网络链接和连接不畅。在这种可疑因素很多的情况下,使用像 OpenResty XRay 这样的动态追踪工具可以更加容易地解决这些棘手的问题。

分析过程:慢速 TCP 连接上的抓包

响应延迟的分布

OpenResty XRay 首先对客户生产环境中的 web 服务器(这里是指 OpenResty 或 Nginx web 服务器)处理的请求进行采样。OpenResty XRay 的一个优点是,它可以安全地分析在线应用程序和服务器,而不对运行中的用户进程做改动。

然后它自动为响应延迟创建下面显示的对数分布图。

Nginx 请求延迟分布图,5 个慢请求落在 131ms ~ 262ms 区间

注意,有 5 个请求延迟较长,时长在 131ms ~ 262ms 的范围内。

最慢的请求

OpenResty XRay 还自动收集了那些最慢的请求的 URI 和其他信息。

最慢请求明细表——所有慢速连接都指向 /view/shopcart/ 这个 URI

出于保护隐私的原因,我们改了这里的 Host 名。

从上表中可以看出来,所有慢请求的目标都是 URI /view/shopcart/

智能 Nginx 抓包

OpenResty XRay 有一个独特的功能,就是可以只在我们感兴趣的慢速连接上捕捉和分析 TCP 数据包。例如在上面这种情况下,我们只在请求延迟超过 100ms 的 TCP 连接上抓包。

OpenResty XRay 自动识别了那些缓慢的 TCP 连接,并捕获了其中的 TCP 数据包。其中一个样本在 OpenResty XRay 的 web 控制台中看起来是这样的。

慢速连接的 TCP 抓包时间线,显示一个 ACK+PUSH 入站数据包之前有 200ms 的间隔

在这个图表上,小圆圈代表服务器的 ingress 数据包,而方块则代表 egress 数据包。

在图表中,有一个数据包的延迟非常长,大约 200ms。就是这个 “ACK+PUSH” 数据包,它是用小圆圈标识的,这意味着它是一个从客户端发送的入站或 ingress 数据包。

从这一点我们可以排除应用服务器或网关 web 服务器的原因。一定是在客户端或客户端和服务器之间的网络链接处多出了这个额外的 200ms 的延迟。(想了解 Java Tomcat 技术栈上类似的单请求抓包诊断案例,可参考 Java Tomcat 响应慢:用单请求 PCAP 精准定位慢请求。)

根因:客户端延迟发送请求体

检查客户端和服务器之间的网络链接是否有缺陷很简单。我们的客户随后将注意力转移到他们的安卓移动应用程序的客户端应用程序上。

很快他们发现,客户端软件故意在发送请求头和发送请求体之间增加了 200ms 的延迟——这正是 Nginx 读取请求体延迟的根因。谜底解开了!

修复后的延迟表现

从下面的新的 OpenResty XRay 请求延迟分布图可以看出,在客户修复了其客户端应用中的额外延迟后,200ms 的长延迟问题已经不复存在。

修复客户端延迟后的请求延迟分布图——200ms 的离群点已消失

常见问题

如何做到只在慢速连接上抓取 TCP 数据包?

OpenResty XRay 的智能抓包在连接级别做过滤——设定一个延迟阈值(例如 100ms),它就只在请求延迟超过该阈值的 TCP 连接上抓包。这种有选择的抓包方式避免了对所有连接抓包,因此不会影响生产服务器的性能。

Nginx 读取请求体延迟是什么原因造成的?

在本文的案例中,Nginx 读取请求体的延迟是由客户端应用故意在发送请求头之后延迟 200ms 才发送请求体造成的。长延迟也可能有其他原因,比如磁盘 I/O 速度慢、内核网络堆栈或其他网络设备的数据包丢失、CPU 使用率高,或者网络链接和连接不畅。针对慢速连接的 TCP 抓包可以帮助缩小排查范围,确定具体是哪个因素导致的。

如何从抓包结果判断延迟出在客户端?

在抓包时间线上,先看延迟的数据包是哪一方发出的。如果一个来自客户端的入站数据包——比如携带请求体的 ACK+PUSH 数据包——是在一段很长的时间间隔之后才到达的,那么延迟就出在客户端或网络一侧。在本文的案例中,200ms 的间隔出现在一个入站的 ACK+PUSH 数据包之前,而网络链接又被确认没有问题,因此延迟直接指向了客户端应用。

智能抓包会影响生产服务器的性能吗?

不会。OpenResty XRay 只在请求延迟超过设定阈值的连接上抓包,绝大多数连接完全不受影响。本文中的客户就是在生产环境中直接运行的,没有产生任何性能影响。

全自动化的分析

OpenResty XRay 可以自动选择合适的分析器对目标进程进行采样,自动分析生成的火焰图,最后在自动分析报告中以人性化的形式呈现出分析结果。这将会更加方便客户使用,他们不必整天盯着服务器,也不必手动运行合适的分析器,甚至不必理解分析器本身采样的结果。

OpenResty XRay 日报

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. 公司的博客网站 。也欢迎扫码关注我们的微信公众号:

我们的微信公众号

翻译

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