跳转至

性能调优

文档版本: 1.0.0 最后更新: 2026-06-08 Git 提交: b9fa976b 作者: Lincoln

本文档提供 JAiRouter 分布式追踪系统的性能调优指南和最佳实践。

采样策略优化

生产环境推荐配置 (v2.7.9+)

jairouter:
  tracing:
    sampling:
      # 采样策略(issue #234 起真实存在):ratio(默认,只按采样率)/ rule(按 rules 匹配 span 属性,
      # 未命中回落 ratio)/ adaptive(用 adaptive.* 的上下限,需 adaptive.enabled=true)。
      # 原 `default-ratio` 键不存在,已删除。
      strategy: ratio
      ratio: 0.1                       # 10% 采样率 (v2.7.9+ 优化: 从 1.0 降低)

      # 始终采样的路径
      always-sample:
        - "/api/v1"
        - "/api/security"

      # 从不采样的路径
      never-sample:
        - "/health"
        - "/actuator"

      # 自适应采样配置 (可选)
      adaptive:
        enabled: false                  # 启用自适应采样
        target-spans-per-second: 1000   # 目标每秒 Span 数量
        min-ratio: 0.1                  # 最小采样率
        max-ratio: 1.0                  # 最大采样率
        adjustment-interval: 30         # 调整间隔 (秒)

自适应采样策略

启用后,自适应采样根据系统负载动态调整采样率:

// AdaptiveSamplingStrategy 根据以下因素调整:
// - 每个 span 名称的请求频率
// - 系统负载阈值
// - 可配置的最小/最大采样率

// TracingConfiguration.SamplingConfig.AdaptiveConfig 配置:
// - enabled: 默认 false
// - targetSpansPerSecond: 1000
// - minRatio: 0.1
// - maxRatio: 1.0
// - adjustmentInterval: 30 秒

内存管理优化

内存配置

jairouter:
  tracing:
    performance:
      # 内存管理配置
      memory:
        max-spans-in-memory: 10000     # 内存中最大 Span 数量
        memory-limit-mb: 100           # 内存限制 (MB)
        gc-interval: 60s               # 垃圾回收间隔

      # 缓冲区配置
      buffer:
        size: 1024                     # 缓冲区大小
        flush-interval: 5s             # 刷新间隔
        max-wait-time: 30s             # 最大等待刷新时间

自动内存清理

系统根据配置的内存限制自动清理过期的 Span:

// MemoryConfig 默认值:
// - maxSpansInMemory: 10000
// - memoryLimitMb: 100
// - gcInterval: 60 秒

// 当超过内存阈值时:
// 1. 优先清除最旧的 Span
// 2. 根据 gcInterval 触发 GC
// 3. 发送监控指标

异步处理优化

线程池配置

jairouter:
  tracing:
    performance:
      # 线程池配置
      thread-pool:
        core-size: 2                   # 核心线程数(boundedElastic 的 threadCap,即线程上限)
        queue-capacity: 1000           # 队列容量
        keep-alive: 60s                # 空闲线程存活时间(boundedElastic 的 TTL)
        thread-name-prefix: "tracing-" # 线程名前缀

      # 异步处理
      async-processing: true           # 启用异步处理

该线程池是 Reactor 的 Schedulers.newBoundedElastic(threadCap, queuedTaskCap, prefix, ttlSeconds), 没有 core/max 之分:core-size 就是上限。因此 thread-pool.max-size 只是被 /actuator/info 回显、不影响行为,tracing-base.yml 里已不再登记它(issue #220)。

批处理配置

jairouter:
  tracing:
    performance:
      # 批处理器参数就在这里 —— OpenTelemetry 的 BatchSpanProcessor 由这几个值驱动
      # (见 OpenTelemetryAutoConfiguration#tracerProvider),没有第二套开关。
      #
      # 核对(issue #224):原先上面还有一个 open-telemetry.sdk.trace.processors.batch.* 子段
      # (schedule-delay / max-queue-size / max-export-batch-size / export-timeout),
      # **没有任何生产代码读它**,调了不生效,字段与 yml 键已一并删除。
      batch:
        size: 100                      # 最大导出一批的 Span 数(setMaxExportBatchSize)
        timeout: 5s                    # 导出超时,同时也是调度延迟(setExporterTimeout + setScheduleDelay)
        max-concurrent-batches: 3      # 应用侧批处理的并发度
      buffer:
        size: 8192                     # 队列上限(setMaxQueueSize 取的是 buffer.size)

导出器优化

导出器配置

jairouter:
  tracing:
    exporter:
      type: "otlp"                     # jaeger, zipkin, otlp, logging

      # OTLP 导出器 (推荐)
      otlp:
        endpoint: "http://localhost:4317"
        timeout: 10s
        compression: "gzip"            # 启用压缩
        headers: {}

      # Jaeger 导出器 (已弃用,建议使用 OTLP)
      jaeger:
        endpoint: "http://localhost:14268/api/traces"
        timeout: 10s

      # Zipkin 导出器
      zipkin:
        endpoint: "http://localhost:9411/api/v2/spans"
        timeout: 10s

      # 日志导出器 (用于调试)
      logging:
        enabled: false
        level: "INFO"

JVM 调优

推荐 JVM 参数

# 生产环境 JVM 参数
-Xmx4g -Xms4g                     # 堆内存配置
-XX:+UseG1GC                      # 使用 G1 垃圾收集器
-XX:MaxGCPauseMillis=200          # 最大 GC 暂停时间
-XX:+UnlockExperimentalVMOptions
-XX:+UseJVMCICompiler             # 启用 JVMCI 编译器 (可选)

# 对于追踪密集型工作负载,建议:
-XX:InitiatingHeapOccupancyPercent=35  # 更早触发 GC
-XX:G1HeapRegionSize=16m               # 更大的区域以提高吞吐量

监控指标

关键性能指标

# CPU 使用率
jairouter_tracing_cpu_usage

# 内存使用
jairouter_tracing_memory_used_bytes

# Span 处理延迟
jairouter_tracing_span_processing_duration_seconds

# 导出成功率
jairouter_tracing_export_success_rate

# 队列大小
jairouter_tracing_queue_size

# 活跃 Span 数
jairouter_tracing_active_spans

监控配置

jairouter:
  tracing:
    monitoring:
      metrics:
        traces:
          histogram-buckets: [0.1, 0.5, 1.0, 2.0, 5.0, 10.0, 30.0]  # 处理延迟直方图桶(秒)
      health:
        enabled: true
        check-interval: 30s
      alerts:
        thresholds:
          memory-usage: 0.8         # 堆使用率 > 80% 时判内存瓶颈
          export-latency-p99: 5000  # trace.export 的 P99 > 5 秒时判操作瓶颈

已删除:self-monitoring、metrics.enabled、metrics.prefix、metrics.traces.enabled、 metrics.exporter.*、alerts.enabled、alerts.thresholds.export-failure-rate 与 queue-size —— 这些键能绑定但全仓无任何读者(/actuator/info 也不回显 monitoring 段),留着会让人以为改它有效 (issue #224)。

故障排除

性能问题诊断

  1. 检查采样率是否过高
  2. 验证 jairouter.tracing.sampling.ratio 是否适合您的流量
  3. v2.7.9+ 默认为 0.1 (10%),从 1.0 (100%) 降低

  4. 监控内存使用

  5. 检查 jairouter_tracing_memory_used_bytes
  6. 必要时调整 performance.memory.max-spans-in-memory

  7. 分析 GC 频率和耗时

  8. 使用 JVM GC 日志: -Xlog:gc*:file=gc.log
  9. 如果 GC 频繁,考虑增加堆大小

  10. 检查导出器响应时间

  11. 监控 jairouter_tracing_export_success_rate
  12. 验证到 OTLP/Jaeger 端点的网络连接

  13. 验证队列压力

  14. 检查 jairouter_tracing_queue_size
  15. 必要时增加 performance.thread-pool.queue-capacity

优化建议

  • 根据实际负载调整采样率 (v2.7.9+ 优化默认值: 10%)
  • 启用异步处理 减少阻塞 (async-processing: true)
  • 配置批处理 提高导出效率
  • 监控系统资源使用 使用内置指标
  • 使用 OTLP 导出器 配合 gzip 压缩获得最佳性能
  • 定期清理过期数据 配置 GC 间隔

组件特定优化

HTTP 追踪

jairouter:
  tracing:
    components:
      http:
        enabled: true
        capture-headers: true
        capture-body: false           # 禁用以提高性能
        max-body-size: 1024
        excluded-paths:               # 排除高流量路径
          - "/health"
          - "/metrics"

数据库追踪

核对(issue #224):这一段配置不存在。components.database(enabled / capture-sql / max-sql-length)在全仓没有任何消费方,属"配了不生效",字段与 tracing-base.yml 里的键已删除。 需要数据库侧的可观测性时,应先实现消费方再加回配置。

限流器与熔断器追踪

jairouter:
  tracing:
    components:
      rate-limiter:
        enabled: true
        capture-algorithm: true
        capture-statistics: true

      circuit-breaker:
        enabled: true
        capture-state: true
        capture-statistics: true

已删除(issue #224):capture-quota / capture-decision(限流器)、capture-state-changes / capture-failure-rate(熔断器)、capture-selection / capture-candidates(负载均衡器)。 这些字段既没有消费方,也不被 /actuator/info 回显 —— 改它们没有任何可观测后果。 留下来的 capture-* 的唯一消费者就是那份回显,同样不改变采集行为。

下一步