You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保OpenTelemetry Sidecar等待客户端完成数据刷入?

解决OpenTelemetry Sidecar提前关闭导致的指标刷入失败问题

问题背景

采用Sidecar架构部署OpenTelemetry:业务服务生成指标/追踪数据,AWS OTel Collector Sidecar负责收集并推送到AWS。Docker Compose配置如下:

services:
  service:
    build:
      context: .
    image: service
    container_name: service
    ports:
      - "3000:3000"
    depends_on:
      - aws-otel-collector
  aws-otel-collector:
    image: public.ecr.aws/aws-observability/aws-otel-collector:latest
    container_name: aws-otel-collector
    ports:
      - "4317:4317"

业务服务在关闭时会通过defer逻辑刷入指标并关闭exporter:

shutdown, err := initMetricProvider(ctx)
if err != nil {
    log.Fatal(err)
}
defer func() {
    log.Printf("Shutting down metric provider")
    if err := shutdown(ctx); err != nil {
        log.Fatal(fmt.Errorf("failed to shutdown metric provider: %w", err))
    }
}()

meter := global.MeterProvider().Meter("service")
counter, err := meter.SyncInt64().Counter("test")

重启服务时偶尔出现连接失败错误:

max retry time elapsed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:4317: connect: connection refused"

根因是Sidecar在业务服务完成指标刷入前被暂停,导致服务无法连接Collector提交数据。

解决方案

1. 调整Docker Compose容器停止策略

Docker Compose默认停止顺序为启动顺序的反向(先停业务服务,再停Sidecar),但默认仅等待10秒就会强制杀死未退出的容器。可以延长业务服务的停止等待时间,确保其完成指标刷入:

修改业务服务的Compose配置,添加stop_grace_period:

services:
  service:
    # ... 原有配置 ...
    stop_grace_period: 30s  # 延长停止等待窗口,给足指标刷入时间
  aws-otel-collector:
    # ... 原有配置 ...

此配置会让Compose在发送停止信号后,等待30秒再强制杀死业务服务,同时保证Sidecar在业务服务完全退出后才停止。

2. 给Sidecar添加关闭延迟

通过自定义入口脚本,让AWS OTel Collector在收到停止信号后先等待一段时间再关闭,给业务服务预留数据提交时间:

  1. 创建entrypoint.sh脚本:
#!/bin/bash
# 启动Collector进程
/otelcol-contrib &
COLLECTOR_PID=$!

# 处理停止信号
stop_collector() {
    echo "Received stop signal, waiting 10s before shutting down collector..."
    sleep 10
    kill $COLLECTOR_PID
    wait $COLLECTOR_PID
}

# 捕获SIGTERM和SIGINT信号
trap stop_collector SIGTERM SIGINT

# 等待Collector进程结束
wait $COLLECTOR_PID
  1. 修改Sidecar的Compose配置,挂载脚本并替换入口点:
services:
  aws-otel-collector:
    # ... 原有配置 ...
    volumes:
      - ./entrypoint.sh:/entrypoint.sh
    entrypoint: ["/bin/bash", "/entrypoint.sh"]

3. 优化服务端关闭逻辑

增强业务服务的shutdown逻辑,添加超时控制和重试机制,提高指标刷入的成功率:

defer func() {
    log.Printf("Shutting down metric provider")
    // 创建带超时的上下文,延长刷入等待时间
    shutdownCtx, cancel := context.WithTimeout(ctx, 15*time.Second)
    defer cancel()
    
    if err := shutdown(shutdownCtx); err != nil {
        log.Printf("Initial shutdown failed: %v", err)
        // 重试2次,避免短暂的Sidecar不可用
        for i := 0; i < 2; i++ {
            log.Printf("Retrying shutdown attempt %d...", i+1)
            time.Sleep(2 * time.Second)
            if err := shutdown(shutdownCtx); err == nil {
                log.Printf("Shutdown succeeded on retry")
                return
            }
        }
        log.Fatal(fmt.Errorf("Final shutdown failed: %w", err))
    }
}()

4. 修正服务与Sidecar的连接地址

在Docker Compose环境中,业务容器应通过服务名aws-otel-collector访问Sidecar,而非127.0.0.1(后者指向业务容器自身)。检查服务的OpenTelemetry exporter配置,确保endpoint设置为aws-otel-collector:4317,避免因网络地址错误导致的连接失败。

内容的提问来源于stack exchange,提问作者k-sever

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 07:15:29