如何获取Nginx Ingress Controller中请求的等待时长?
我们基于Kubernetes+Nginx Ingress Controller运行多后端服务平台,采用New Relic、Prometheus和Grafana实现可观测性监控与告警,Nginx Ingress是所有请求的入口。当后端服务线程全部繁忙时,请求会在Nginx侧排队,直至资源释放后才会被处理。目前无法找到能体现请求被Nginx接收后、交由后端处理前等待时长的指标。
Nginx Ingress Controller提供的Prometheus延迟指标包含以下4个:
nginx_ingress_controller_request_duration_seconds(对应Nginx变量request_time)nginx_ingress_controller_response_duration_seconds(对应Nginx变量upstream_response_time)nginx_ingress_controller_connect_duration_seconds(对应Nginx变量upstream_connect_time)nginx_ingress_controller_header_duration_seconds(对应Nginx变量upstream_header_time)
经负载测试与指标分析,这些指标仅覆盖Nginx接收请求后的延迟,均不包含请求被Nginx接收前的等待时长。
问题与解答
1. upstream_connect_time是否包含请求被Nginx接收前的等待时长?
不包含。upstream_connect_time仅统计Nginx与后端服务器建立TCP连接的耗时,即从Nginx发起连接请求到连接成功的时间区间,完全属于Nginx接收请求后的操作阶段,与接收前的等待无关。
2. 上述4个指标中是否有包含请求被Nginx接收前的等待时长的?
没有。这四个指标的时间起点均为Nginx完成请求接收之后:
request_time:从Nginx接收请求第一个字节到发送响应最后一个字节的总时长;upstream_response_time:Nginx向后端发送请求到收到后端响应最后一个字节的时长;upstream_header_time:Nginx发送请求到收到后端响应第一个字节的时长;upstream_connect_time:如前所述,仅统计后端连接建立耗时。
所有指标均不涉及Nginx接收请求前的等待阶段。
3. upstream_queue_time变量是否能体现请求被Nginx接收前的等待时长?是否仅Nginx Plus支持?
首先纠正认知:upstream_queue_time统计的是请求被Nginx接收后、等待分配后端连接的时长,也就是Nginx内部的排队等待时间,并非“接收前”的等待时长。
该变量在开源版Nginx(包括Nginx Ingress Controller基于的开源Nginx)中即可支持,并非Nginx Plus专属。若要将其暴露为Prometheus指标,需修改Nginx Ingress Controller的配置,启用对upstream_queue_time的指标采集,最终会生成类似nginx_ingress_controller_upstream_queue_duration_seconds的指标(具体名称可能因Ingress Controller版本略有差异)。
4. 还有其他方式可了解请求被Nginx接收前的等待时长吗?
请求被Nginx接收前的等待,本质是请求在Nginx监听套接字队列中等待被处理的时间(即TCP层面的backlog排队)。可通过以下两种方式获取相关信息:
- TCP层面间接监控:通过Prometheus采集节点的TCP指标,比如
node_netstat_TcpExtListenOverflows(监听队列溢出次数)、node_netstat_TcpExtListenDrops(监听队列丢弃的请求数),这些指标可间接反映是否存在请求在Nginx接收前排队,但无法直接获取单个请求的等待时长。 - 客户端侧计时估算:在请求发起端记录请求发送时间,与后端服务接收请求的时间做差值,该差值包含网络传输、Nginx接收前排队、Nginx处理的总耗时;再减去已知的网络传输耗时和Nginx处理耗时,即可估算出接收前的等待时长。这种方式需要客户端配合,且精度依赖计时同步。
内容的提问来源于stack exchange,提问作者Raman Kishore

