深入 OpenTelemetry 11 - Flush、Shutdown 与进程退出的三个边界
订单请求完成意味着业务工作已经返回,不意味着后台 Batch 队列已排空。进程退出前调用 flush、正常 shutdown 与强制终止,有什么可观测的差异?本篇把“生成三条”“出口报告成功”“本地 HTTP 端点收到三条”分开记录,而不把它们统称为已落库。
完成信号的范围
| 阶段 | 能说明 | 不能说明 |
|---|---|---|
span.end() |
Span 的结束逻辑已执行 | Batch 已取出队列 |
forceFlush().join(limit) |
在期限内等待已有处理器完成 | 超时后结果必然失败或服务器持久化 |
shutdown().join(limit) |
处理器关闭路径得到结果 | Collector 或后端可查询 |
| 测试端点收到 protobuf | HTTP 路径确实有网络接收 | 数据会长期保留 |
固定 SHA 的 SdkTracerProvider.forceFlush 组合处理器结果;BatchSpanProcessor.forceFlush 通知 worker 排空当前队列,worker flush 循环 导出队列里的数据,然后完成对应 result。shutdown 先 flush 后关 exporter,二次调用在该处理器层直接返回成功。它不能恢复上一篇已经因队列满而被丢弃的 Span。
CompletableResultCode.join 最多等待给定时长;超时返回的是原结果对象,并不会自动把它标记为失败,要另外检查 isDone() 和 isSuccess()。上游 BatchSpanProcessorTest.shutdownFlushes 检查正常关闭会 flush;上游 testQueueSizeSmallerThanMaxBatchWithForceFlush 检查未达批量阈值仍可导出。这是对固定源码及上游测试的静态阅读,本机运行事实在下一节。
正常退出与强制退出
ExitTraceProducer 是教学子进程:用 Batch 配置 maxExportBatchSize=16、scheduleDelay=1h,生成三条 Span 后不依赖短期定时触发导出。正常路径显式 forceFlush().join(5s) 与 shutdown().join(5s),子进程 exit 0;Lab11Test 的本地 HTTP 接收端解析 OTLP protobuf,新增三条。另一个全新子进程生成三条后调用 Runtime.getRuntime().halt(0):绕过清理路径,父测试确认端点新增零条。该强制退出只针对教学环境的批量参数和此次运行,不能外推为“所有异常退出必丢三条”;如果 Span 已在退出前导出,结果会不同。
独立的限时反例使用闩锁卡住 Batch worker 内的教学 exporter:在 exporter 已进入的屏障之后,forceFlush().join(100ms) 返回但 isDone() 仍为 false;放行后 join(5s) 返回 success。这里的 exporter 只是本地阻塞替身,不是第 10 篇的网络出口;测试用它隔离“等到超时”与“异步执行最终完成”两个状态。
运行 JAVA_HOME=/tmp/otel-20260930/jdk-extract/usr/lib/jvm/java-21-openjdk-amd64 ./mvnw -q -pl sdk-labs -Dtest=Lab11Test test,真实摘要:
1 | |
HTTP 接收端只回 200,既没有 Collector 处理器、持久化,也没有后端查询。第 10 篇还表明 HTTP 200 可能对应 protobuf 的部分拒收;本篇端点没有发送部分成功响应,因此这里“收到三条”严格限定为教学端点解析出三条。
误解与练习
“join(100ms) 返回就表示 flush 成功”不成立:必须查结果状态。“Runtime.halt(0) 返回码为零就表示遥测已发完”也不成立:本次仍有三条未抵达测试接收端。“flush 成功等于后端可查询”缺少 Collector、后端与查询证据。
练习一。 保持相同两个子进程,把 Batch 阈值调成 1,再重跑。记录强制退出前测试端点接收数是否变化,不要把原有的零条结论当作所有配置的必然结果。
练习二。 在限时等待反例中把 join(100ms) 后的断言改成直接断言 isSuccess(),确认为何断言失败;用 CompletableResultCode.join 的实现解释失败和超时未完成的差别。
导航与参考资料
09 队列与丢弃 · 10 OTLP/HTTP · 当前篇:11 Flush 与 Shutdown · 12 Instrument 选择。
参考资料:固定 SHA c25c0a0ee0da01ab2f74ba83052d1c249ed57020 的 SdkTracerProvider、BatchSpanProcessor、CompletableResultCode 与上游测试(固定链接见正文);本地记录 examples/opentelemetry-java/evidence/11/RUN.md。
