客户端HTTP请求超时分析与处理

658 阅读5分钟

一个客户端要通过 http 请求得到服务端的响应,要经过的环节还挺多的,通常,客户端要先从本地 DNS 获得请求域名的 ip 地址解析,然后经本地 SNAT,请求来到公网,到达 CDN、再经过 WAF,来到服务端的防火墙城下,经 DNAT,到达服务端内部,再由服务端内部反向代理(通常是 nginx)到真正请求的业务处理系统,业务系统处理完成后再原路返回到客户端。这中间任何环境发生问题或者处理时间过长,都可能会导致请求超时的发生。

所以,我们经常碰到的问题就是,客户又又又反馈超时了!

遇到此类问题,首先判断请求超时发生在何时何处,大致可以分为三类:

  1. 发生在客户端请求域名解析时,属于域名解析超时
  2. 发生在客户端到 CDN 至 nginx 之间,属于网络超时
  3. 发生在服务端系统内部,属于内部服务超时。

域名解析超时问题处理

一般可能是客户端网络或者本地 DNS 配置出了问题,可以让客户在本地 ping 或者解析其他常见域名测试。
服务端域名权威解析服务器有问题也不是不可能,这就要求我们平时做好对外服务域名可用性监控告警,做好应急方案,一旦解析服务器发生故障,可以启用备用方案。

客户端到 CDN 到 WAF 到防火墙到 Nginx 超时处理

通过对比相同时间段,相同客户端 IP,相同域名和相同请求路径的 CDN、WAF、nginx 的日志,可以确定超时发生在何处;如果客户提供了诸如订单号之类的请求参数,也可以在 nginx 日志中搜索该日志(假设 nginx 日志配置了打印请求参数)。

客户端到 CDN 超时

如果客户反馈超时,但是我们查询 CDN 日志该客户的客户端 IP 在该时段的请求,未发现响应时间长的请求或499,504等异常响应码,则判断超时发生在客户端至 CDN 之间。
整体思路:

  1. 首先协助客户排除本地网络问题;
  2. 协助客户检查 local dns 与 ip 是否属于同一地域的同一运营商网络,如果不是,与客户评估及说明影响或建议客户调整 local dns 以获得最佳的 CDN 节点调度;
  3. 协助客户排查运营商网络或 CDN 节点问题;
  4. 如果 CDN 节点问题,与 CDN 厂家报障,同时协助客户临时更改 local dns 以暂时恢复业务。 详细可参考下图:
    image.png CDN访问异常排查思路

CDN 回源 WAF 超时

CDN 日志存在超时,WAF 及 nginx 日志未发现超时等异常。可以检查 CDN 配置的回源地址,查看是否存在异常,并及时向 WAF 厂家保障。

WAF 到 Nginx 超时

waf 到 nginx 之间的网络一般会经过防火墙,将公网 IP 转换为 nginx 的内网ip,这个环节的超时表现为 waf 存在响应时间长或者 499、504 等异常响应码的日志,nginx 上却是正常响应且响应时间正常,或者 nginx 上直接没有日志。 以阿里云 waf 为例,http 请求经过 waf 后,waf 会生成一个 traceid 加入 http 请求头传递到下游,我们在 nginx 配置将其打印到日志中,同时打印 remote_addr 和 remote_port 即 waf 作为 nginx 客户端的 ip 和 tcp 端口。如此,我们就可以跟踪分析 http 请求在 waf、防火墙及 nginx 的日志。

这段链路涉及到 waf 厂家,运营商网络以及防火墙DNAT等多个环节,在实际工作中经过观察,发现超时经常发生在tcp建连阶段,如果将waf回源连接改为长连接,减少建连次数,将减少超时次数,另外,可以针对导致建连超时的两个主要直接原因进行优化:

单纯的网络链路问题

waf 回源时选择一个公网 ip 建立 tcp 超时,再重试第二个ip,如果第一个ip建立tcp连接超时时间过长或者没有重试机制,则会导致超时,因此可以根据业务场景需要,配置较短的网络连接超时时间(注意不是http响应超时时间),增加重试次数,比如下图所示:

image.png 如此,从 waf 日志上看,第一次tcp建连超时后,又重试了第二次,整体响应时间在1秒多一点内完成,大部分业务场景是可以接受的。

waf 回源配置多个公网 ip 映射到相同内网IP导致的问题

假设 nginx 刚关闭了一个 waf 过来的tcp连接,此时,nginx 上的该连接处于time-wait状态,此时同一个 waf ip 使用相同端口与不同的回源 IP 的 http/https 端口建立连接,如果这个公网 ip 也映射到相同的 nginx 内网 ip 上,nginx 所在主机会将新建连接的 syn 包 rst 掉。

image.png

针对此问题的办法可以是将多个公网 ip 映射到多个不同的内网 ip ,使其保持一一对应关系,可以减少问题发生的概率。

系统内部超时

nginx日志配置打印 upstream_connect_time、upstream_response_time,通过这两个参数,可以判断是业务系统内部超时还是nginx与业务系统之间的网络超时。

内部网络问题

通常 nginx 和 upstream 在同一个内网,网络延迟很少,一般一个 upstream 有多个 server,某个 server 问题,及时替换即可。

内部服务处理时间过长

通过分析日志,或者链路跟踪,找到处理时间长的环节,定位到具体问题再进行优化处理,可能是上游响应时间过长,也可能是内部某个服务有问题,或者中间件、数据库等问题。