Jaeger v2 存储集成测试 E2E 模式全解析:架构设计、数据流与本地运行指南

发布时间:2026/9/13 5:05:34
Jaeger v2 存储集成测试 E2E 模式全解析:架构设计、数据流与本地运行指南 Jaeger v2 存储集成测试 E2E 模式全解析架构设计、数据流与本地运行指南【免费下载链接】jaegerCNCF Jaeger, a Distributed Tracing Platform项目地址: https://gitcode.com/GitHub_Trending/ja/jaeger导读本文基于仓库内 cmd/jaeger/internal/integration/README.md 展开深入讲解 CNCF Jaeger 分布式追踪平台 v2基于 OpenTelemetry Collector 构建的存储集成测试体系。你将理解单元模式与E2E 模式两类测试的本质区别掌握 SpanWriter/SpanReader 如何通过 RPC 客户端驱动真实 Jaeger-v2 二进制、storagecleaner 扩展如何实现测试间的存储隔离以及 Kafka、gRPC 两种特殊拓扑下的完整数据流最终学会用一条 make 命令在本地跑通任意后端的集成测试。一、什么是 Jaeger v2 集成测试两种测试模式的对比Jaeger v2 的集成测试位于 cmd/jaeger/internal/integration它并非独立发明的新测试框架而是对既有integration.StorageIntegration测试套件的扩展专门用于测试 Jaeger-v2 的 OtelCol 二进制。目前该测试套件**只覆盖 span storeSpan 存储**这一能力域。仓库中存在两套互补的测试路径README 将它们分别称为模式位置数据访问方式单元模式unit modeinternal/storage/integration直接调用存储 API 读写 Span 数据E2E 模式e2e modecmd/jaeger/internal/integration通过 RPC 客户端读写 Span 数据驱动真实的 Jaeger-v2 OtelCol 二进制两者共用同一套StorageIntegration测试用例区别在于被测对象和通信方式单元模式绕过了整个 Collector 管线直接对着存储接口做断言而 E2E 模式将 Jaeger-v2 作为独立进程启动测试进程通过网络与其交互——写入走 OTLP Receiver读取走 jaeger_query 扩展gRPC API v3。这种设计使得 E2E 模式能够覆盖最完整、最真实的生产链路从 OTLP 数据进入 Collector、经过 pipeline 中的 processor/exporter最终落到存储后端再从查询接口读回。测试跑的是用户实际部署的形态而不是存储层的孤立单元。二、总体架构写入路径与读取路径README 用一张 mermaid 流程图概括了 E2E 模式的核心架构整个链路被清晰地划分为两个子系统集成测试可执行文件Integration Test Executable运行go test的测试进程包含测试主体、SpanWriter、SpanReader 以及各自的 RPC 客户端。jaeger-v2 二进制作为独立 OS 进程被测试拉起内部运行着 OTLP Receiver、Exporter 与 jaeger_query 扩展。2.1 写入路径SpanWriter → OTLP ReceiverSpanWriter 的实现位于 trace_writer.go它复用 OpenTelemetry Collector 官方otlpexporter组件将测试产生的 Span 数据通过 OTLP 协议发送到 Jaeger-v2 的接收端口。关键细节包括目标端口为常量otlpPort 4317见 e2e_integration.go即 Jaeger-v2 默认的 OTLP gRPC 接收端口关闭了重试RetryConfig.Enabled false与发送队列QueueConfig设为None保证每个 Span 的发送行为可预期便于定位问题分块大小MaxChunkSize 5WriteTraces会把批量数据按每 5 个 Span 切分成多个 chunk 分别发送。源码注释说明这是为了显式控制 chunk 边界不再依赖上游批处理确保 OTLP Kafka 导出路径安全地低于消息大小上限同时仍能覆盖 Jaeger v2 管线依赖的分块逻辑分块时使用 jptrace.SpanIter 迭代按 Resource/Span 层级重建ptrace.Traces结构。2.2 读取路径SpanReader → jaeger_querySpanReader 的实现位于 trace_reader.go它通过 gRPC 连接 Jaeger-v2 的查询服务使用api_v3.QueryServiceClientproto 定义见 internal/proto/api_v3目标端口为ports.QueryGRPC16685。该客户端实现了tracestore.Reader接口支持GetTraces按 TraceID 逐条拉取api_v3 不支持批量 multi-get因此逐个 ID 发起流式请求GetServices/GetOperations查询服务与操作列表FindTraces按服务名、操作名、标签、时间范围、时长等参数搜索支持结构化过滤器结构化过滤是 RFC 0005 引入的 alpha 能力默认关闭需要显式开启 feature gateFindTraceSummaries摘要查询远端不支持时返回ErrUnsupported。两个组件各自实现了io.Closer测试结束时由t.Cleanup统一关闭连接。从源码结构看这套 writer/reader 的抽象目标就是让同一套StorageIntegration测试用例既能跑单元模式也能无缝切换到 E2E 模式。三、测试隔离的关键storagecleaner 扩展集成测试要求每个用例之间存储数据互相独立。E2E 模式下测试进程无法直接操作存储因此仓库实现了一个专用的storage_cleaner扩展来解决清理问题其独立模块说明见 storagecleaner/README.md。3.1 工作原理扩展在 Collector 进程中开放一个 HTTP 端点POST /purge处理流程如下见 extension.go扩展Start时调用jaegerstorage.GetPurger(config.TraceStorage, host)实现见 jaegerstorage/extension.go从jaegerstorage扩展中取出指定名称的存储工厂若该工厂实现了storage.Purger接口则将工厂包装为 purge handlerhandler 收到POST /purge请求后调用purger.Purge(ctx)成功返回 HTTP 200 与提示文本失败返回 500。扩展实现了extensioncapabilities.Dependent接口其Dependencies()声明对jaegerstorage扩展的依赖见 extension.go确保依赖的存储扩展先于它启动。3.2 为什么不在标准组件集里因为POST /purge会删除存储中的全部追踪数据且没有任何鉴权生产环境中暴露该端点极其危险。因此 storagecleaner刻意不注册到标准 Jaeger 组件集internal.Components()而是只在测试二进制jaeger-e2e中注册——入口见 jaeger-e2e/main.gofunc main() { factories, err : internal.Components() if err ! nil { log.Fatal(err) } cleaner : storagecleaner.NewFactory() factories.Extensions[cleaner.Type()] cleaner if err : jaegercli.NewCommand(factories).Execute(); err ! nil { log.Fatal(err) } }也就是说jaeger-e2e 标准jaeger组件集 storage_cleaner扩展它只存在于测试环境永远不会随用户发行版分发。3.3 配置说明与自动注入storagecleaner 的配置结构见 config.go核心配置项如下配置项必填默认值说明trace_storage是valid:required—jaegerstorage扩展中定义的存储后端名称port否9231HTTP 服务监听端口常量定义于 extension.go手动配置示例来自 storagecleaner/README.mdextensions: storage_cleaner: trace_storage: storage_nameE2E 测试并不要求手工编写这段配置而是通过 e2e_integration.go 的createStorageCleanerConfig函数自动注入到cmd/jaeger/目录下的标准 Collector 配置中。注入逻辑值得展开读取原始 YAML向service.extensions追加storage_cleaner推导trace_storage的值优先从jaeger_query扩展的storage.traces字段获取若不存在则回退到remote_storage扩展的storage字段对 Elasticsearch / OpenSearch 后端还会额外把jaeger_storage.backends.some_storage中的service_cache_ttl调整为1ms让新写入的服务能立即被查询命中将改写后的 YAML 写入临时目录返回新配置文件路径。测试进程侧的清理函数purge见 e2e_integration.go向http://0.0.0.0:9231/purge发起 POST并支持通过环境变量PURGER_ENDPOINT覆盖地址。每个存储后端的具体测试如 badger_test.go都会把purge挂到StorageIntegration.CleanUp上从而在用例之间自动清理数据。四、Kafka 集成测试引入消息中间件的复杂拓扑Kafka 测试与其他集成测试的核心差异在于数据流路径标准测试中 Span 由 SpanWriter 经 RPC 客户端直达 Collector 的 Receiver再经 Exporter 写入存储而 Kafka 测试在 Collector 与存储之间插入了 Kafka 消息队列构成Collector → Kafka → Ingester → 存储的完整链路flowchart LR Test --|writeSpan| SpanWriter SpanWriter -- RPCW[RPC_client] RPCW -- OTLP_Receiver[Receiver] OTLP_Receiver -- CollectorExporter[Kafka Exporter] CollectorExporter -- Kafka[Kafka] Kafka -- IngesterReceiver[Kafka Receiver] IngesterReceiver -- IngesterExporter[Exporter] IngesterExporter -- StorageBackend[(In-Memory Store)] Test --|readSpan| SpanReader SpanReader -- RPCR[RPC_client] RPCR -- QueryProcess[jaeger_query] StorageCleaner --|purge| StorageBackend QueryProcess -- StorageBackend subgraph Integration_Test_Executable Test SpanWriter SpanReader RPCW RPCR end subgraph Jaeger Collector OTLP_Receiver CollectorExporter end subgraph Jaeger Ingester IngesterReceiver IngesterExporter QueryProcess StorageBackend StorageCleaner[Storage Cleaner Extension] end subgraph Kafka Topic end4.1 两个二进制、两个进程与其它测试不同Kafka 场景下**Collector并不直接访问存储**真正持有存储、提供查询能力的是Ingester。因此 kafka_test.go 复用了E2EStorageIntegration结构体来管理两个二进制jaeger-v2-collector加载 config-kafka-collector.yaml只做接收 OTLP → 导出到 Kafka设置SkipStorageCleaner: truejaeger-v2-ingester加载 config-kafka-ingester.yaml从 Kafka 消费并写入内存存储同时承载 jaeger_query 与 storagecleaner健康检查端口覆盖为14133避免与 Collector 冲突。4.2 覆盖的编码格式与同步写入路径TestKafkaStorage通过 table-driven 的方式对四种 Kafka 消息编码各跑一遍完整测试套件编码KAFKA_ENCODING说明otlp_protoOTLP protobuf 编码otlp_jsonOTLP JSON 编码jaeger_protoJaeger protobuf 编码jaeger_jsonJaeger JSON 编码每次运行使用jaeger-spans-纳秒时间戳形式的唯一 topic避免并发执行时数据互相污染通过EnvVarOverrides把KAFKA_TOPIC与KAFKA_ENCODING注入两个二进制的环境变量。此外TestKafkaStorage_SyncElasticsearch专门验证 RFC 0007 的至少一次at-least-once同步写入路径Collector → Kafka → Ingester → Elasticsearchingester 处于同步写模式write_mode: sync、poison_pill_handling: drop、阻塞发送队列、message_marking.after。该测试依赖 Kafka 与 Elasticsearch 同时运行仓库提供的 scripts/e2e/kafka.sh 会同时拉起两者。五、gRPC 集成测试通过 gRPC 访问远程存储gRPC 测试验证的是**Collector 通过 gRPC 协议代理远程存储**的架构将 Collector 与 Remote Storage Backend 分成两个可独立部署的进程flowchart LR Test -- |writeSpan| SpanWriter Test -- |HTTP/purge| PurgeEndpoint SpanWriter -- |0.0.0.0:4317| OTLP_Receiver1 OTLP_Receiver1 -- GRPCStorage GRPCStorage -- |0.0.0.0:4316| OTLP_Receiver OTLP_Receiver -- |write| Storage Test -- |readSpan| SpanReader SpanReader -- |0.0.0.0:16685| QueryExtension QueryExtension -- GRPCStorage GRPCStorage -- |0.0.0.0:17271| RemoteStorageAPI RemoteStorageAPI -- |read| Storage PurgeEndpoint -- |purge| Storage subgraph Integration Test Executable Test SpanWriter SpanReader end subgraph Collector OTLP_Receiver1[OTLP Receiver] QueryExtension[Query Extension] GRPCStorage[gRPC Storage] end subgraph Remote Storage Backend OTLP_Receiver[OTLP Receiver] Storage[(In-Memory Store)] subgraph remote_storage extension RemoteStorageAPI[gRPC Endpoint] end subgraph storage_cleaner extension PurgeEndpoint[Purge Endpoint] end end5.1 端口与角色对照结合 grpc_test.go 与上述架构图各端口职责如下端口所在进程职责4317CollectorOTLP Receiver接收 SpanWriter 写入的 Span16685CollectorQuery Extensionapi_v3 gRPC服务 SpanReader 的查询4316Remote Storage BackendOTLP Receiver接收来自 Collector gRPC Storage 代理的写入由环境变量REMOTE_STORAGE_BACKEND_GRPC_ENDPOINT0.0.0.0:4316指定17271Remote Storage Backendremote_storage 扩展的 gRPC 端点向 Collector 提供读取 API9231Remote Storage Backendstorage_cleaner 的 purge 端点供测试清理内存存储5.2 测试组织TestGRPCStorage在CUSTOM_STORAGE ! true时先启动远程后端加载 config-remote-storage-backend.yaml健康检查端口12133、指标端口8887再启动 Collector加载 config-remote-storage.yaml。Collector 侧设置SkipStorageCleaner: true因为存储在后端进程里并通过PropagateEnvVars透传REMOTE_STORAGE_ENDPOINT、REMOTE_STORAGE_WRITER_ENDPOINT给二进制。若设置了CUSTOM_STORAGEtrue测试会跳过内置后端启动让用户接入自定义的远端存储实现。六、在本地运行集成测试README 给出了最核心的本地运行命令STORAGE{STORAGE_NAME} make jaeger-v2-storage-integration-test其中存储名称可选badgercassandragrpckafkamemory_v2query从源码看测试目录中还提供了 clickhouse、elasticsearch、opensearch、tail-sampling 以及向后兼容backward compatibility等更多测试入口分别对应 clickhouse_test.go、elasticsearch_test.go、opensearch_test.go、tailsampling_test.go、backward_compatibility_test.go。这些测试在 CI 中由 scripts/e2e 下的脚本如 cassandra.sh、clickhouse.sh、elasticsearch.sh先拉起对应依赖数据库、Kafka 等后再执行。6.1 make 目标做了什么jaeger-v2-storage-integration-test目标定义在 scripts/makefiles/IntegrationTests.mk其执行序列很有参考价值用go build -cover -covermodeatomic构建./cmd/jaeger/jaeger-e2e二进制带插桩覆盖计数go clean -testcache强制作废旧的测试缓存因为外部环境可能已变化通过JAEGER_BINARY_COVERDIR环境变量指定二进制覆盖计数目录运行测试包./cmd/jaeger/internal/integration测试结束后用go tool covdata textfmt把二进制侧的覆盖计数转换为 profile再用 gocovmerge 合并进总覆盖率报告——由于测试通过独立进程驱动二进制go test -coverpkg无法观测到它这套二进制自带插桩 合并 covdata的机制专门解决了这个问题。6.2 测试进程如何管理二进制生命周期测试基础设施在 binary.go 中封装了进程管理值得学习的设计点启动就绪探测进程拉起后轮询健康检查端口默认ports.CollectorV2HealthChecks的GET /status等待 JSON 响应Status StatusOK才继续超时一分钟优雅关闭停止时先发SIGTERM让二进制走完 Collector 的 Shutdown hooks 与存储 Close 调用这些逻辑在 SIGKILL 下会被跳过从而掩盖 bug超过默认一分钟defaultShutdownTimeout仍未退出才升级为SIGKILL日志收集stdout/stderr 分别写入临时目录的output_logs.txt/error_logs.txt测试失败时自动 dump 并以 GitHub Actions 折叠分组输出便于定位。6.3 指标快照每次 E2E 测试结束后框架还会在t.Cleanup中从指标端口默认8888可通过MetricsPort覆盖如 gRPC 远程后端用8887抓取GET /metrics把快照写入仓库根的.metrics/metrics_snapshot_storage.txt见 e2e_integration.go为后续对比不同后端/版本的指标表现提供了原始素材。七、小结一套测试多级保障通过上述剖析可以看到Jaeger v2 存储集成测试是一套精心设计的端到端验证体系测试用例层复用integration.StorageIntegration保证单元模式与 E2E 模式覆盖同一套断言语义通信层SpanWriter 用官方 OTLP exporter 写、SpanReader 用 api_v3 gRPC 读完全走线上协议而非进程内直调隔离层storagecleaner扩展以无鉴权的POST /purge换取测试间的数据独立并通过对jaeger-e2e专用二进制与配置自动注入将风险严格封锁在测试环境拓扑层通过 KafkaCollector Ingester 双进程、gRPCCollector Remote Backend 双进程等测试矩阵覆盖了消息中间件与远程存储这两类最复杂的生产部署形态。对开发者而言STORAGEname make jaeger-v2-storage-integration-test一条命令即可验证某个存储后端在 Jaeger v2 全链路下的读写正确性对追踪平台使用者而言理解这套测试的架构也就理解了 Jaeger v2 中数据从 OTLP 注入到查询返回所经过的每一个关键环节。【免费下载链接】jaegerCNCF Jaeger, a Distributed Tracing Platform项目地址: https://gitcode.com/GitHub_Trending/ja/jaeger创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询