4. 延迟类SLI口径设计:请求延迟、服务端延迟、网络延迟、端到端延迟的测量口径

延迟是衡量系统响应速度的核心指标,也是SRE黄金信号之一。不同观测视角下的延迟含义差异巨大:客户端感知的“慢”与服务端统计的“快”可能同时成立。本章从四个关键口径出发,逐一拆解其测量边界、统计方法与常见陷阱。

4.1 延迟SLI的四类口径概览

口径类型 测量起点 测量终点 典型场景
请求延迟 客户端发出请求 客户端收到完整响应 API网关、前端监控
服务端延迟 服务端接收请求 服务端发出响应 应用服务器、微服务
网络延迟 数据包离开源端 数据包到达目的端 负载均衡、跨AZ通信
端到端延迟 用户操作触发 用户看到最终结果 全链路追踪、用户体验
关键原则:延迟SLI必须明确“从哪到哪”的测量边界。同一个请求,不同口径的延迟值可能相差数倍,混淆口径会导致SLO目标错位。

4.2 请求延迟:客户端视角的“真实感受”

请求延迟(Request Latency)在客户端侧测量,包含完整的网络往返时间(RTT)、服务端处理时间、以及响应数据传输时间。这是用户直接感知的延迟。

  • 测量点:浏览器/移动端SDK/API网关出口
  • 统计口径:从TCP连接建立(或HTTP请求发出)到最后一个字节接收完毕
  • 常见陷阱:客户端DNS解析时间、TLS握手时间是否计入?建议单独记录,避免与业务延迟混淆
  • 推荐分位:p50(中位数)、p95(第95百分位)、p99(第99百分位)
# 请求延迟计算示例(PromQL风格)
# 客户端侧:请求开始到结束的时间差
request_latency_seconds = request_end_timestamp - request_start_timestamp

# 按分位聚合(假设已记录到histogram)
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

4.3 服务端延迟:排除网络干扰的“纯处理时间”

服务端延迟(Server Latency)仅测量服务进程内部的处理耗时,排除网络传输、客户端排队等外部因素。它是容量规划和性能优化的核心依据。

  • 测量点:服务框架拦截器/中间件(如Spring Filter、gRPC Interceptor)
  • 统计口径:从请求到达服务进程(反序列化完成)到响应发出(序列化开始前)
  • 常见陷阱:线程池排队等待时间是否计入?建议区分“队列等待”与“实际处理”,分别记录
  • 推荐分位:p50、p99、p999(用于识别长尾)
实践建议:服务端延迟应同时记录“CPU耗时”和“墙钟耗时”。墙钟耗时包含I/O等待(如数据库查询、下游RPC),CPU耗时仅反映计算密集度。两者差值过大说明存在阻塞点。

4.4 网络延迟:基础设施的“传输代价”

网络延迟(Network Latency)衡量数据包在网络上传输的单向或往返耗时。它通常由网络设备、链路距离、拥塞程度决定,与应用代码无关。

子类型 测量方式 典型值参考
单向延迟(OWD) 源端打时间戳,目的端比对NTP同步时钟 同AZ:<1ms;跨Region:10-100ms
往返延迟(RTT) Ping/TCP握手时间/HTTP首字节时间(TTFB) 同机房:<0.5ms;公网:20-200ms
应用层网络延迟 TTFB - 服务端处理时间 通常占端到端延迟的30%-70%
注意:不要将服务端延迟与网络延迟简单相加得到端到端延迟。客户端请求延迟 = 网络延迟(请求方向)+ 服务端延迟 + 网络延迟(响应方向)+ 数据传输时间。其中数据传输时间与响应体大小强相关。

4.5 端到端延迟:用户体验的“最后一公里”

端到端延迟(End-to-End Latency)从用户发起操作开始,到用户界面完成渲染或反馈结束。它包含客户端处理、网络传输、服务端处理、以及前端渲染的全部环节。

  • 测量点:真实用户监控(RUM)、合成监控(Synthetic Check)
  • 统计口径:用户点击 → 页面首屏渲染 / API响应展示
  • 常见陷阱:前端JavaScript执行时间、图片懒加载、客户端缓存命中是否计入?建议按“关键用户操作”定义测量边界
  • 推荐分位:p75(用户体验基线)、p95(容忍上限)、p99(不可用阈值)
# 端到端延迟分解(示例:Web页面加载)
e2e_latency = dns_lookup + tcp_connect + tls_handshake + 
              request_network + server_processing + 
              response_network + dom_parsing + resource_loading + 
              javascript_execution + rendering

4.6 四类延迟口径的关联与对比

以下SVG图展示了一个典型HTTP请求从客户端到服务端再到客户端的完整路径,并标注了四类延迟的测量边界。

四类延迟口径测量边界对比 客户端 (浏览器/APP) 网络(请求) DNS + TCP + TLS 服务端 (应用+DB+缓存) 网络(响应) 数据传输 渲染 请求延迟(客户端视角) 服务端延迟 网络延迟(RTT = 请求网络 + 响应网络) 端到端延迟(用户操作 → 用户看到结果) 说明: • 请求延迟 = 网络延迟(请求)+ 服务端延迟 + 网络延迟(响应)+ 数据传输 • 服务端延迟仅包含服务进程内部处理时间,不包含网络传输 • 端到端延迟还包含客户端渲染时间,是用户体验的直接度量

4.7 口径选择决策矩阵

在实际SLI设计中,应根据SLO目标和观测角色选择合适口径。以下矩阵帮助快速决策:

SLO目标 推荐口径 理由
用户体验承诺 端到端延迟 直接反映用户感受,包含所有环节
API性能承诺 请求延迟 客户端视角,包含网络但排除前端渲染
服务容量规划 服务端延迟 排除网络波动,聚焦服务处理能力
基础设施SLA 网络延迟 衡量网络质量,与应用代码解耦
故障定位 四类口径同时采集 通过差值定位瓶颈环节
最佳实践:建议同时采集服务端延迟和请求延迟。两者差值即为“网络+传输”开销。当请求延迟恶化而服务端延迟正常时,问题大概率在网络或客户端侧;反之则问题在服务端内部。

4.8 延迟口径设计的常见陷阱与避坑

  • 陷阱1:时钟不同步——分布式系统中各节点时钟偏差会导致延迟计算错误。解决方案:使用NTP对齐,或采用客户端单点打时间戳(如HTTP请求头记录时间)。
  • 陷阱2:排队时间归属不清——请求在负载均衡器、线程池、消息队列中的等待时间应单独记录,避免与服务端处理时间混淆。
  • 陷阱3:长尾请求被平均掩盖——仅看平均延迟会掩盖p99甚至p999的异常。必须使用分位统计,并设置独立的SLO阈值。
  • 陷阱4:重试请求污染统计——客户端自动重试会导致延迟分布失真。建议在SLI中标记重试请求,或仅统计首次请求。
  • 陷阱5:缓存命中与未命中混在一起——缓存命中请求的延迟远低于未命中请求。建议分别统计,或按缓存状态分层。

以下SVG图展示了一个完整的延迟分解结构,帮助理解各环节的归属关系。

延迟分解结构:从用户操作到最终响应 用户操作触发 客户端处理(JS/渲染/缓存) 网络传输(请求+响应) 服务端处理(应用+DB+下游) 延迟口径归属: • 端到端延迟 = 全部四层 • 请求延迟 = 客户端处理 + 网络传输 + 服务端处理 • 服务端延迟 = 仅服务端处理 • 网络延迟 = 仅网络传输 注意: 客户端处理时间常被忽略, 但在移动端可能占端到端 延迟的30%以上。
总结:延迟SLI口径设计的核心是“明确边界、分解环节、分位统计”。在Metric Design实践中,建议为每个口径创建独立的metric,并在metric label中标注口径类型(如 latency_type="server"、latency_type="e2e"),以便在仪表盘和告警中灵活切换视角。