bigywater.tech
微服务 · 92

Sidecar 的资源开销:延迟与内存

加一个 sidecar 到底要付出多少延迟、CPU 和内存?两个 sidecar、再加 mTLS 会怎样?响应变大呢?这篇用 Envoy 1.39.3、nginx 后端和自己写的 Go 压测程序,在本机回环上把直连、一个 Envoy、两个 Envoy、两个 Envoy 加 mTLS 逐一量出来。

+82 µs
一个 Envoy 相对直连多出的平均延迟(43 → 124 µs,本机回环,keep-alive)
85 µs
两个 Envoy 处理一个请求消耗的 CPU(并发 32,Envoy 单线程)
约 44 KB
静态配置里每多一个集群,Envoy 多占的内存(5000 个集群 262 MB)

延迟

实测 · 本机执行输出
  路径               | 平均 µs | p50 µs | p90 µs | p99 µs | 请求/秒(并发 1) | 3 轮平均延迟范围(µs) | 失败
  A 直连             | 43    | 38     | 57     | 96     | 23173      | 42~43         | 0 
  B 一个 Envoy       | 124   | 115    | 158    | 229    | 8003       | 124~126       | 0 
  C 两个 Envoy(明文)   | 218   | 204    | 256    | 378    | 4581       | 214~225       | 0 
  D 两个 Envoy(mTLS) | 223   | 210    | 266    | 381    | 4464       | 220~229       | 0 
  相对直连多出的平均延迟:一个 Envoy +82 µs,两个 Envoy(明文)+175 µs,两个 Envoy(mTLS)+181 µs;p99 分别 +133 / +282 / +285 µs。D 与 C 只差几微秒;我的解释是 mTLS 握手只在建连时发生、已经建好的连接上只多了加解密,这个解释没有单独验证

每多一跳 Envoy,平均延迟多约 80 µs;mTLS 在建好的连接上只多几微秒。

吞吐与 CPU

实测 · 本机执行输出
  路径               | 请求/秒  | p50 µs | p99 µs | Envoy CPU µs/请求 | 3 轮平均延迟范围(µs) | 失败
  A 直连             | 92324 | 299    | 1111   | 0               | 343~349       | 0 
  B 一个 Envoy       | 26419 | 1178   | 1912   | 37              | 1200~1242     | 0 
  C 两个 Envoy(明文)   | 19297 | 1600   | 3043   | 85              | 1621~1659     | 0 
  D 两个 Envoy(mTLS) | 18034 | 1709   | 3347   | 90              | 1751~1799     | 0 
  压测程序、nginx、Envoy 在同一台机器上抢 CPU,直连(A)的吞吐很可能受压测程序自己限制,不是 nginx 的极限;表里 CPU 一列是 Envoy 自己的,不含 nginx 和压测程序

并发 32 时一个 Envoy 的吞吐是直连的约 29%,两个是约 21%;Envoy 的 CPU 是 37 µs(一个)到 85 µs(两个)每请求。

新建连接

实测 · 本机执行输出
  路径               | 平均 µs | p50 µs | p99 µs | 3 轮平均延迟范围(µs) | 失败
  A 直连             | 324   | 286    | 744    | 319~337       | 0 
  B 一个 Envoy       | 370   | 335    | 808    | 281~413       | 0 
  C 两个 Envoy(明文)   | 497   | 447    | 1004   | 487~524       | 0 
  D 两个 Envoy(mTLS) | 466   | 435    | 877    | 384~515       | 0 
  相对直连多出的平均延迟:一个 Envoy +46 µs,两个 Envoy +172 µs,两个 Envoy(mTLS)+141 µs

每次新建连接时第一跳多约 46 µs,两个 Envoy 多约 172 µs,这一节的 mTLS 与明文的差别在噪声里。

大响应

实测 · 本机执行输出
  路径               | 平均 µs | p50 µs | p99 µs | 响应吞吐 MB/s | 3 轮平均延迟范围(µs) | 失败
  A 直连             | 108   | 97     | 239    | 945       | 105~110       | 0 
  B 一个 Envoy       | 220   | 206    | 532    | 464       | 209~223       | 0 
  C 两个 Envoy(明文)   | 343   | 329    | 538    | 298       | 337~373       | 0 
  D 两个 Envoy(mTLS) | 385   | 362    | 786    | 266       | 373~403       | 0 
  响应变大之后,两个 Envoy(明文)比直连多出 235 µs,mTLS 比直连多出 277 µs;我的解释是每多一跳就多拷贝一次整个响应体、mTLS 还要多加解密一次,没有单独验证

100 KB 的响应下两个 Envoy 比直连多 235 µs,mTLS 多 277 µs。

内存

实测 · 本机执行输出
  配置里的集群数 | 启动到可连接(s) | 空闲 RSS(MB)
  1       | 0.21      | 40        
  100     | 0.20      | 43        
  1000    | 0.41      | 78        
  5000    | 1.62      | 262       
  按 1 个集群和 5000 个集群之间的差估算,每个集群(含一条路由)大约占 44 KB;这是静态配置的数字,真实的网格里 Envoy 还要为每个集群保存端点、统计项,内存比这个大
  压测之后各 Envoy 的 RSS:B 40 MB, C 第一跳 41 MB, C 第二跳 41 MB, D 第一跳 43 MB, D 第二跳 43 MB
说明(哪些是测到的,哪些没有测)
  每次运行的数字有明显波动:开发中的另一次运行里,并发 1 的平均延迟是 39 / 117 / 207 / 213 µs,新建连接时 D 比 C 慢,内存一节 1000 个集群的 RSS 是 119 MB(这次是 78 MB),5000 个集群是 250 MB(这次是 262 MB),所以微秒级和几十 MB 级的差别不能当精确值;全部在本机回环上,没有容器网络、iptables 重定向(第 83 篇)和跨主机的网络,Envoy 与后端之间的往返比真实部署小得多,绝对数字不能直接套用;每个数字是 3 轮里的中位数那一轮;Envoy 只开了 1 个工作线程;mTLS 的两个 Envoy 之间没有配置 SAN 校验;没有测:HTTP/2 与 gRPC、带 Lua / 限流 / 访问日志等过滤器的 Envoy(第 85 篇测过过滤器链的开销)、开启 tracing 与指标采集、Envoy 与应用同在一个 Pod 时的 CPU 争抢、Istio 的 Envoy 镜像和它默认配置的内存
ERRORS {}

空闲约 40 MB,配置里每多一个集群约多 44 KB;每个 sidecar 都要保存全网格的配置。

分步演示

sidecar 的开销
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.8 / Go / nginx / Envoy / etcd / Consul / Nacos / OpenTelemetry / Prometheus(按各篇注明用到哪些及版本);所有服务都是本机自己起的进程,端口 9150 以上,只监听 127.0.0.1,不连任何外部服务,不碰本机已有的实例;故障用 kill -9 进程、让连接断开或在代码里注入延迟与错误来制造;计时用 time.perf_counter,数字每次运行会有小幅抖动。本机回环(没有容器网络,也没有 iptables 重定向,见第 83 篇);Envoy 1.39.3 用 --concurrency 1;后端是 nginx;压测程序是自己写的 Go 程序;每个数字是 3 轮里的中位数那一轮;数字有明显的运行间波动:开发中另一次运行的并发 1 平均延迟是 39 / 117 / 207 / 213 µs,1000 个集群的 RSS 是 119 MB(这次 78 MB),新建连接一节里 D 比 C 慢(这次反过来)
    • 没有验证:真实容器网络和 iptables 重定向额外的开销;HTTP/2 与 gRPC;带 Lua、限流、访问日志、tracing 过滤器的 Envoy;Istio 的 Envoy 镜像在默认配置下的内存;Envoy 与应用同在一个 Pod 时的 CPU 争抢;mTLS 两个 Envoy 之间没配 SAN 校验;D 与 C 差几微秒的原因(我的解释是握手只在建连时发生)
    京ICP备2026067502号-1京公网安备11010502063487号