OTLP 用 gRPC 还是 HTTP?gzip 能省多少?Collector 的 receiver、processor、exporter 流水线怎么接?batch、filter、resource 各做什么?下游挂了 Collector 能缓冲多少?这篇用 OpenTelemetry Python SDK 和 Collector 逐项量出来。
传输方式 | 应用 → Collector 字节数 | 平均每个 span 的字节数 | Collector → 应用 字节数 | TCP 连接数 | 总耗时(s) ---------------+--------------------+----------------+--------------------+---------+------- gRPC | 4,144,978 | 207.2 | 3,977 | 1 | 0.66 gRPC + gzip | 816,179 | 40.8 | 4,351 | 1 | 0.72 HTTP(protobuf) | 4,148,711 | 207.4 | 4,600 | 1 | 0.65 HTTP + gzip | 818,229 | 40.9 | 4,600 | 1 | 0.71 gRPC 和 HTTP 的负载都是同一个 protobuf 消息,所以不压缩时字节数接近;gzip 把属性里重复的键名和值压缩掉,体积大幅下降;gRPC 复用一条 HTTP/2 连接,HTTP 导出器(requests)的连接数见表
gRPC 和 HTTP 的负载都是 protobuf,不压缩时字节数几乎一样;gzip 把每个 span 压到约 41 字节。
流水线 | file exporter 写出的次数(行数) | span 数 | 平均每次写出的 span 数 | 写完全部 span 的时间(相对 SDK force_flush 返回,s) | 资源属性里的 deployment.* ---------------------+-------------------------+--------+----------------+----------------------------------------+---------------------------- (A)没有处理器 | 40 | 20000 | 500 | 0.05 | (B)batch(2000 / 1 s) | 10 | 20000 | 2000 | 1.04 | (C)resource + filter | 40 | 16000 | 400 | 0.11 | deployment.environment=prod 没有 batch 时 Collector 收到一批就写出一批(每批 512 个);batch 处理器把它们攒到 2000 个或 1 s 再写出,写出次数少、每次更大,代价是最多多等 timeout;filter 处理器丢弃了带 health=true 的 span
batch 把多次写出合成一次,多等 timeout;filter 丢弃指定的 span;resource 统一加资源属性。
下游停掉的时间 | 应用 SDK 的队列大小 | 下游最终收到的 span | 没收到 | Collector 日志 “Rejecting data” 条数 | Collector 日志 “Dropping data” 条数
--------+--------------+--------------+-------+----------------------------------+--------------------------------
3 s | 200000 | 100000 | 0 | 2 | 0
10 s | 200000 | 99800 | 200 | 5 | 2
10 s | 2048 | 49485 | 50515 | 5 | 2
Collector 的 sending_queue 满了会拒收(“Rejecting data”),把压力还给应用的 SDK,由 SDK 的队列和重试继续缓冲;重试超过 max_elapsed_time 的那一批被丢弃(“Dropping data”)。所以丢多少取决于 Collector 队列、重试时间和 SDK 队列三层加起来能缓冲多久
ERRORS {}Collector 的队列满了会拒收,把压力还给 SDK;丢多少取决于 Collector 队列、重试时间和 SDK 队列三层。