尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

服务网格卡顿时先查哪里

服务网格卡顿时先查哪里 服务网格卡顿时先查哪里服务网格中的偶发慢请求不能只盯业务容器日志。请求还会经过代理的连接池、服务发现、重试和上游连接其中任何一层排队业务日志都可能没有对应的慢记录。下面按代理指标、连接状态和路由配置的顺序排查“无业务慢日志”的问题。文中的数值仅用于说明指标含义实际阈值应由服务的基线和服务等级目标决定。# Envoy 内部统计指标发现 upstream 连接池爆满排队 $ curl -s http://127.0.0.1:15000/stats | grep upstream_cx_overflow cluster.outbound|8080||user-service.production.svc.cluster.local.upstream_cx_overflow: 412 cluster.outbound|8080||user-service.production.svc.cluster.local.upstream_cx_connect_timeout: 181. 先确认慢请求停在哪一段当流量穿过 Envoy Sidecar 时一个完整的 HTTP 请求生命周期被拆分成了两个独立的 TCP 连接Client - Inbound Envoy和Outbound Envoy - Upstream Service。可以从 Envoy 的管理接口读取连接池和握手统计再结合抓包或链路追踪核对# 查看指定 Envoy 容器的连接池溢出与握手超时统计 kubectl exec -it order-service-7d8b5c94d-2k9ls -c istio-proxy -- \ curl -s http://127.0.0.1:15000/stats | grep -E (upstream_cx|ssl.handshake) # 对 Envoy 监听的 15001 端口进行 tcpdump 抓包分析 SYN 重传 kubectl exec -it order-service-7d8b5c94d-2k9ls -c istio-proxy -- \ tcpdump -i any port 15001 -nn -vvv -c 100 # 查看 Envoy 路由级的 Pending Requests 数量 curl -s http://127.0.0.1:15000/stats | grep upstream_rq_pending抓包数据揭示了那个神秘“3 秒”的由来Linux 内核 TCP 的初始 SYN 重传超时时间RTO刚好是 3 秒。当业务突发并发流量时Envoy 向下游服务发起的 TCP 连接触发了 EnvoyDestinationRule默认过于保守的maxConnections限速上限。超出上限的连接被 Envoy 直接丢弃或挂起在 Pending 队列中等待 upstream 超时并触发 SYN 重传正好锁死了 3 秒。2. 深入 Envoy stats 指标定位 upstream_cx_overflow 与 TLS 握手延时。为了精准拆解 Envoy 内部消耗的时间我们分析了 Envoy 的双向代理链路定位卡顿的三个核心指标upstream_cx_overflow连接池溢出次数。此数值大于 0 说明maxConnections或http1MaxPendingRequests设得太小upstream_cx_connect_timeoutEnvoy 建连超时。通常意味着目标 Node 网络拥塞或 Kubelet 丢包ssl.handshake.failedmTLS 证书轮换时 Citadel / SDS 密钥协商失败导致连接断开重连。3. 调整 Envoy DestinationRule 连接池与 HTTP2 协议栈参数。确认是 Envoy 连接池与 HTTP/2 多路复用配置不匹配导致阻塞后我们需要通过 Istio 的DestinationRule显式重写连接池参数。下面是修复卡顿问题的DestinationRule精细化调优配置 YAMLapiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: user-service-connection-pool-tuning namespace: production spec: host: user-service.production.svc.cluster.local trafficPolicy: connectionPool: tcp: # 提高 upstream 最大 TCP 连接数防止高并发下连接被强行挂起 maxConnections: 4096 # 显式开启 TCP Keepalive防止防火墙静默断开长连接导致的建连卡顿 tcpKeepalive: time: 30s interval: 5s probes: 3 connectTimeout: 500ms http: # 提高 pending 请求队列上限防止连接池满时直接丢包 http1MaxPendingRequests: 2048 # 单个 HTTP/2 连接允许的最大并行请求数 (充分利用 Multiplexing) maxRequestsPerConnection: 256 # 允许最大请求总数 maxRequests: 8192 # 离群检测熔断机制连续 5xx 错误时快速摘除故障 Pod避免重试卡顿 outlierDetection: consecutive5xxErrors: 3 interval: 10s baseEjectionTime: 30s maxEjectionPercent: 50代码层面如果上游调用方是 Go 语言需要在 HTTP Client 中开启 HTTP/2 协议支持与长连接保活防止在 Pod 本地 loopback 网卡上频繁触发短连接建连package main import ( context fmt net net/http time ) // NewTunedHTTPClient 创建适配 Envoy Sidecar 的高性能 HTTP 客户端 func NewTunedHTTPClient() *http.Client { dialer : net.Dialer{ Timeout: 2 * time.Second, // 建连超时压缩至 2s 内拒绝 3s 默认重传 KeepAlive: 30 * time.Second, // 开启 TCP 保活 } transport : http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: dialer.DialContext, ForceAttemptHTTP2: true, // 强制与 Envoy 走 HTTP/2 多路复用 MaxIdleConns: 500, // 维持足够大的空闲连接池 MaxIdleConnsPerHost: 100, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 2 * time.Second, ExpectContinueTimeout: 1 * time.Second, } return http.Client{ Transport: transport, Timeout: 5 * time.Second, // 总体请求超时限制 } } func main() { client : NewTunedHTTPClient() req, _ : http.NewRequestWithContext(context.Background(), GET, http://user-service:8080/api/v1/users/profile, nil) start : time.Now() resp, err : client.Do(req) duration : time.Since(start) if err ! nil { fmt.Printf(❌ 请求失败: %v\n, err) return } defer resp.Body.Close() fmt.Printf(✅ 请求成功 | 状态码: %d | 耗时: %v\n, resp.StatusCode, duration) }4. 用 OpenTelemetry 拆分 Envoy 链路耗时。调整配置后我们需要利用 OpenTelemetry (OTel) 的分布式追踪在 Jaeger / Tempo 面板中准确拆解 Envoy 内部耗时。在 Envoy 侧配置 tracing 扩展将 Envoy 的 Span 细化为envoy.ingress请求进入侧边栏的时间envoy.egress请求离开侧边栏发往目标的时间。# 验证 OpenTelemetry Trace ID 是否在 Envoy 中成功透传 curl -i -H x-request-id: trace-audit-0830-9981 http://order-service:8080/orders # 观察 Envoy Stats 中 trace 导出成功计数 curl -s http://127.0.0.1:15000/stats | grep tracing.zipkin.reporter.spans_sent通过修改DestinationRule放大 TCP 连接池并将建连超时从默认值切断至 500ms偶发性的 3 秒卡顿彻底消失接口 P99 延迟稳定在16ms ~ 22ms区间upstream_cx_overflow计数器停止翻滚。服务网格卡顿时绝不要盲目怀疑代码。优先查DestinationRule的连接池限额再查内核 TCP 的 RTO 3 秒重传最后看 OpenTelemetry 的 Envoy 细分 Span。这三步跑完绝大多数网格卡顿隐患都会水落石出。
返回列表