服务网格 22:访问日志怎样区分代理失败和业务失败
同一个 503,可能出现在不同的层
客户端看见 503,并不能判断是 inventory 自己返回、代理连接不上库存实例,还是请求根本没有选到可用目标。第 03 篇讨论了 listener、route、cluster 和 endpoint;第 21 篇又加入认证、授权两个可能提前结束请求的位置。访问日志的任务,是把代理观察到的结束原因与应用实际做过的事情对齐,而不是只重复一列 HTTP 状态码。
Envoy 的响应标志、%RESPONSE_CODE_DETAILS%、%UPSTREAM_HOST% 和 %UPSTREAM_TRANSPORT_FAILURE_REASON% 能给出比状态码更细的线索,字段可用性及具体文字随代理版本、过滤器和配置而变。没有匹配 route、上游连接失败、上游主动断开,都需要分别查看代理实际记录;有 UPSTREAM_HOST 也不保证应用处理完请求。客户端侧代理、服务端侧代理、网关和应用还可能各自记录同一个逻辑请求,必须写清观察点。
用请求 ID 对齐三条路径
实验输入固定为 frontend → orders 调用链(orders 先调用 inventory,成功后再调用 external-stub) 的同一只读 SKU,每个场景生成独立 X-Request-ID。在隔离环境启用可检索的 Envoy 访问日志,将请求 ID、响应码、响应标志、详情、上游地址和代理身份一起记录;当前 Go 应用已有 request_id、role、status 日志,可据此判断哪些应用 handler 实际运行。保存代理最终生效的日志配置;“启用了 Telemetry 资源”并不等于采集端收到日志。
第一组正例走正常 quote:从客户端收到的响应回溯 frontend、orders、inventory 和 external-stub 的日志。第二组移除测试路径的 route,仅在明确被改动的代理核对无路由详情和下游响应;不要预设必定是 503,route 匹配失败与目标 cluster 无健康端点也不能合成同一种问题。第三组保持 route 和 endpoint 可见,但让测试 Service 指向没有监听者的上游端口,对照代理连接错误及库存应用是否收到请求。第四组让应用自身返回 503:可以使用现有 frontend 的“候选上游配置为空”分支,但它是应用级空地址配置,不是 Kubernetes 空 EndpointSlice。
| 场景 | 首要取证问题 | 实际标志、详情、应用记录 |
|---|---|---|
正常 quote |
哪些代理和应用见到同一请求 ID? | NOT_RUN:无 Kubernetes/Istio/Envoy |
| 无路由 | 哪个代理提前结束,是否确无上游处理? | NOT_RUN |
| 错误上游端口 | 当前 route/endpoint 是什么,失败在连接哪一段? | NOT_RUN |
| 应用返回 503 | 目标应用是否记录同一 ID 和主动返回的 503? | NOT_RUN |
这些并非“状态码到根因”的静态对照表。如果应用确实返回 503,上游响应标志和详情可能与代理本地生成的 503 不同;如果代理有重试,单个客户端请求又可能对应多个上游尝试。记录每次尝试及最终响应,不用应用的最后一行日志替代客户端结果,更不要把没有应用日志直接当作应用没有执行的充分证明:还要排查采集丢失。
给每个错误保留代理结束原因
以下命令在 examples/service-mesh 目录执行,使用 04 章 Kubernetes 1.33.4 / Istio 1.27.0 sidecar 基线,应用容器名 app。先清理前章授权、故障与出口策略;下列预期值尚不是集群实测结果。
1 | |
mainline/22/logs.yaml 使用默认 envoy 日志 provider;Istio 1.27.0 的默认访问日志含 request ID、response flags、response code details 和 upstream host。如果安装时改过日志格式,应先保存 MeshConfig 并确认字段存在,不能按列位置猜测含义。
1 | |
无路由组预期出现 route_not_found 一类详情与 404;连接组保持路由但 upstream host 端口错误,预期连接失败详情。实际 flags 和错误文字以固定版本日志为准,不把本文写成不可变的状态码字典。配置传播有延迟,需在请求前确认对应代理已同步;若仍看到旧配置,不重复解释旧结果。
应用 503 对照复用 15 章 fault-lab:请求 /quote?mode=fail,保存 fault-a/fault-b 的应用日志以及 sm-probe 的上游响应记录。该组必须实际进入应用,而错误端口组不能由应用主动生成;缺日志时先验证采集完整性。完成后删除 logs.yaml,恢复原 inventory 路由和 Service,后续排障可按需保留日志配置但应注明。
固定源码入口:Istio 1.27.0 pilot/pkg/model/telemetry.go。该链接用于核对配置生成或执行机制;完整资源和命令保存在 examples/service-mesh/mainline/22/。静态检查通过不等于集群实验通过。
练习与参考解答
- 两条客户端日志都是 503,其中一条
inventory有同一请求 ID 的 503 应用日志,另一条完全没有。可以确定第二条是无路由吗?参考解答:不能;还可能连接失败、日志未采集或请求被认证授权提前结束。先比对对应代理的 route、响应详情、上游地址及日志采集完整性。 - 看到
UPSTREAM_HOST,是否可以断言业务写入成功?参考解答:不能。它只帮助定位代理选择或尝试的上游;写入要核对应用处理记录和最终副作用账本。
官方资料与系列导航
- Istio Envoy Access Logs:默认格式及可配置日志入口。
- Envoy access logging:访问日志格式与字段。
- Envoy response code details:代理结束请求的细分原因,实测时以冻结版为准。
系列导航:21 认证成功为何仍会被拒绝 → 22 访问日志怎样区分代理失败和业务失败(本文)→ 23 网格指标怎样用于 SLO。
