分布式链路追踪选型:Jaeger vs Zipkin实战对比

2026-07-12 9 min read 5

一次线上故障让我不得不选链路追踪

2023年双11大促,我们一个核心API接口突然从50ms飙到3s。排查了半小时——日志没报错,监控CPU正常,数据库慢查询也没有。最后靠人工翻代码,发现是某个下游服务超时重试导致雪崩。这种故障,没有链路追踪就是瞎子。

当时我们只有Prometheus做指标监控,但指标只能告诉你“慢了”,不能告诉你“哪里慢”。于是决定上分布式链路追踪。选型时在Jaeger和Zipkin之间纠结,两个都试了一遍,踩了不少坑。这篇文章直接给结论:小团队选Zipkin,大流量选Jaeger。下面展开说为什么。

方案对比:Jaeger vs Zipkin

架构差异

Jaeger(v1.52)和Zipkin(v2.24)都是基于Google Dapper论文实现,但架构不同:

  • Jaeger:使用gRPC协议,支持自适应采样,存储后端支持Elasticsearch、Cassandra、Kafka。组件包括agent、collector、query、ingester。
  • Zipkin:使用HTTP协议,存储后端支持Elasticsearch、Cassandra、MySQL。组件包括collector、storage、query、web UI。

性能对比(压测数据)

指标JaegerZipkin
单机吞吐(span/s)150008000
P99延迟(采样率100%)2.3ms5.1ms
内存占用(1000 span/s)256MB180MB
存储成本(ES索引)高(多字段索引)

压测环境:PHP8.3 + Laravel11 + MySQL8.0.35 + Elasticsearch7.17.9,单机4C8G。使用wrk压测,每个请求产生10个span。

完整代码实现

1. Jaeger集成(PHP + OpenTelemetry)

<?php
// composer require open-telemetry/opentelemetry-auto-jaeger
use OpenTelemetry\SDK\Trace\TracerProvider;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\Contrib\Jaeger\Exporter;

$exporter = new Exporter(
    'my-service',
    'http://jaeger-collector:14268/api/traces'
);

$tracerProvider = new TracerProvider(
    new SimpleSpanProcessor($exporter)
);

$tracer = $tracerProvider->getTracer('my-service');

// 创建根span
$span = $tracer->spanBuilder('http.request')->startSpan();
$span->setAttribute('http.method', 'GET');
$span->setAttribute('http.url', '/api/order');

// 模拟业务逻辑
usleep(100000); // 100ms

$span->end();
$tracerProvider->shutdown();

2. Zipkin集成(PHP + cURL)

<?php
// 使用Zipkin官方PHP库
use Zipkin\TracingBuilder;
use Zipkin\Samplers\BinarySampler;
use Zipkin\Reporters\Http;

$endpoint = 'http://zipkin:9411/api/v2/spans';
$reporter = new Http($endpoint);
$sampler = BinarySampler::createAsAlwaysSample();

$tracing = TracingBuilder::create()
    ->havingLocalServiceName('my-service')
    ->havingSampler($sampler)
    ->havingReporter($reporter)
    ->build();

$tracer = $tracing->getTracer();

$span = $tracer->newTrace()->setName('http.request');
$span->start();
$span->tag('http.method', 'GET');
$span->tag('http.url', '/api/order');

usleep(100000);

$span->finish();
$tracer->flush();

3. Docker Compose部署

version: '3.8'
services:
  jaeger:
    image: jaegertracing/all-in-one:1.52
    ports:
      - '16686:16686'  # UI
      - '14268:14268'  # HTTP collector
      - '4317:4317'    # gRPC
    environment:
      - COLLECTOR_OTLP_ENABLED=true
      - SPAN_STORAGE_TYPE=elasticsearch
      - ES_SERVER_URLS=http://elasticsearch:9200

  zipkin:
    image: openzipkin/zipkin:2.24
    ports:
      - '9411:9411'
    environment:
      - STORAGE_TYPE=elasticsearch
      - ES_HOSTS=http://elasticsearch:9200

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.9
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m

4. 自适应采样配置(Jaeger)

# jaeger-sampling.yaml
service_strategies:
  - service: my-service
    type: probabilistic
    param: 0.1  # 10%采样率
  - service: my-service
    type: rate_limiting
    param: 10   # 每秒最多10个span

5. 批量发送优化(Zipkin)

<?php
// 使用Zipkin的AsyncHttpReporter实现批量发送
use Zipkin\Reporters\Http\AsyncHttpReporter;
use Zipkin\Reporters\Http\ClientFactory;

$clientFactory = new ClientFactory();
$reporter = new AsyncHttpReporter(
    $clientFactory,
    $endpoint,
    [
        'batch_size' => 100,  // 每100个span发送一次
        'flush_interval' => 5 // 最多5秒发送一次
    ]
);

效果数据

上线后,我们对核心接口做了压测对比:

场景无追踪JaegerZipkin
P99延迟50ms52.3ms55.1ms
CPU使用率30%35%33%
内存占用200MB256MB230MB

结论:Jaeger性能损耗略低,但内存占用更高。Zipkin更轻量,适合资源受限场景。

避坑指南

坑1:采样率设100%导致存储爆炸

上线第一天,Jaeger的Elasticsearch索引每天增长50GB。原因是采样率设了100%,每个请求产生10个span,QPS 2000,一天就是17亿条span。解决方案:生产环境用自适应采样,核心接口10%,非核心1%。

坑2:Zipkin的HTTP协议在高并发下丢数据

压测到8000 QPS时,Zipkin的collector开始返回503。原因是HTTP请求排队,客户端超时丢弃。解决方案:改用Jaeger的gRPC协议,或者给Zipkin加Kafka缓冲。

坑3:时间戳不同步导致链路断裂

跨服务器调用时,如果服务器时间差超过1秒,链路会显示为两条独立trace。解决方案:所有服务器统一使用NTP,并配置chronyd同步。

坑4:Elasticsearch版本不兼容

Jaeger 1.52要求ES 7.x,Zipkin 2.24支持ES 7.x和8.x。我们一开始用了ES 8.0,Jaeger直接报错。解决方案:严格按照官方文档选择版本。

总结

选型没有银弹。小团队、低流量选Zipkin,部署简单,资源占用低。大流量、高并发选Jaeger,性能更好,支持gRPC和自适应采样。无论选哪个,一定要控制采样率,否则存储成本会让你哭。

IT搬运工

专注技术分享,坚持原创深度内容。

分类
链接
订阅

RSS 订阅关注最新文章

© 2026 IT搬运工 · 站点地图 · 鄂ICP备19007640号-3