OTCA — 오픈텔레메트리 인증 어소시에이트 · 샘플링과 운영 · 실습
컬렉터는 200을 돌려줬는데 스팬은 어디에도 없었다
목표
백엔드가 멈추거나 요청을 거절할 때 컬렉터의 큐·재시도 설정에 따라 호출자가 받는 응답과 내부 텔레메트리 지표가 어떻게 달라지는지 실제로 재고, 짧은 장애를 유실 없이 넘기는 설정을 설계합니다.
왜 중요한가
애플리케이션이 200 을 받았다는 사실은 스팬이 저장소에 닿았다는 뜻이 아닙니다. 큐는 호출자를 장애에서 떼어 놓는 대신 유실을 컬렉터 안으로 옮기고, 재시도는 일시적 실패만 구해 주며, 한도가 지나면 데이터는 로그 한 줄과 지표 하나만 남기고 사라집니다. otelcol_receiver_accepted_spans·otelcol_exporter_sent_spans·send_failed·enqueue_failed 를 나란히 읽을 줄 알아야 파이프라인 유실을 진단할 수 있습니다.
준비된 환경
python3 /opt/fixtures/otca_backpressure_lab.py init 이 /root/otca-export/ 에 broken.yaml 과 spans.json(요청 한 번에 스팬 2개)을 둡니다. python3 /opt/fixtures/otca_backpressure_lab.py run 설정.yaml [--backend down|ok|reject] [--backend-after 초] [--requests N] [--wait 초] 은 lab-k8s 의 otelcol-contrib 0.116.0 을 실제로 띄워 요청을 0.2초 간격으로 보내고, 기다린 뒤 컬렉터 내부 텔레메트리의 otelcol_* 지표를 읽어 요약합니다. otlphttp 익스포터의 endpoint 는 실험용 수신기로 바꿔 끼웁니다(down 은 아무도 듣지 않는 포트, ok 는 200, reject 는 400). 채점기는 같은 조건으로 여러분의 설정을 다시 돌려 적은 숫자와 대조합니다.
단계
1. python3 /opt/fixtures/otca_backpressure_lab.py init 으로 재료를 만든 뒤 otelcol-contrib validate --config /root/otca-export/broken.yaml 을 실행합니다. /root/otca-export/01-validate.txt 에 missing_component=(오류가 가리키는 없는 구성요소)를 적고, 파이프라인이 정의된 otlphttp/backend 로 내보내도록 고친 /root/otca-export/fixed.yaml 을 만드세요.
2. /root/otca-export/no-queue.yaml 을 fixed.yaml 에서 만들고 otlphttp/backend 에 sending_queue.enabled: false, retry_on_failure.enabled: false 를 넣습니다. python3 /opt/fixtures/otca_backpressure_lab.py run /root/otca-export/no-queue.yaml(백엔드 down, 요청 5번 × 스팬 2개) 결과를 /root/otca-export/02-no-queue.txt 에 codes=, accepted_spans=, refused_spans=, send_failed_spans= 로 옮기세요.
3. /root/otca-export/queue.yaml 에서 sending_queue 와 retry_on_failure 를 켭니다(다른 값은 기본값). 같은 방식(백엔드 down)으로 돌려 /root/otca-export/03-queue.txt 에 codes=, accepted_spans=, sent_spans=, send_failed_spans= 를 적으세요.
4. /root/otca-export/small-queue.yaml 에 sending_queue: {enabled: true, queue_size: 2, num_consumers: 1}, retry_on_failure: {enabled: true, initial_interval: 1s, max_interval: 1s} 를 둡니다. 백엔드 down 으로 돌려 /root/otca-export/04-full.txt 에 codes=, accepted_spans=, refused_spans=, enqueue_failed_spans=, queue_size= 를 적으세요.
5. 같은 small-queue.yaml 을 --backend ok --backend-after 2.5 --wait 6 으로 돌립니다(2.5초 뒤 수신기가 뜸). /root/otca-export/05-recover.txt 에 accepted_spans=, sent_spans=, send_failed_spans= 를 적으세요.
6. queue.yaml 을 --backend reject(수신기가 HTTP 400 을 돌려줌)로 돌립니다. /root/otca-export/06-permanent.txt 에 codes=, sent_spans=, send_failed_spans=, dropping_logged=(로그에 Dropping data 가 있었는지 true/false), retried=(수신기가 받은 요청 수 backend_requests 가 요청 5번보다 많았는지 true/false)를 적으세요.
7. /root/otca-export/short-retry.yaml 에 retry_on_failure 를 initial_interval: 500ms, max_interval: 500ms, max_elapsed_time: 2s 로 둡니다(큐는 기본값). 백엔드 down, --wait 6 으로 돌려 /root/otca-export/07-give-up.txt 에 accepted_spans=, sent_spans=, send_failed_spans=, dropping_logged= 를 적으세요.
8. /root/otca-export/resilient.yaml 을 설계합니다. 채점기는 --backend ok --backend-after 4 --requests 8 --wait 8 조건으로 돌려, 호출자에게 거절이 0건이고 8초 안에 스팬 16개가 모두 전송되며 실패가 0건인지 확인합니다. python3 /opt/fixtures/otca_backpressure_lab.py run /root/otca-export/resilient.yaml --backend ok --backend-after 4 --requests 8 --wait 8 로 먼저 확인하세요.
참고
- 수락(accepted)·거절(refused)은 리시버, 전송(sent)·전송 실패(send_failed)·큐 넣기 실패(enqueue_failed)는 익스포터 지표입니다.
- 흔한 실수: 200 응답을 전달 완료로 읽는 것, 큐를 키우면 유실이 없어진다고 보는 것(재시도 한도·메모리·재시작), 400 도 재시도될 것이라 기대하는 것.
- 이 실습의 큐는 메모리 큐라 컬렉터가 재시작하면 비워집니다. 영속 큐(storage 확장)는 다루지 않습니다. 숫자는 이 버전과 짧은 실험 조건에서 잰 값입니다.
- [Exporter helper](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md) · [Internal telemetry](https://opentelemetry.io/docs/collector/internal-telemetry/)
단계 8개
- 기동 전에 잡을 수 있었던 오류
- 큐도 재시도도 없을 때
- 200 을 받았는데 전송은 0
- 큐가 차면 거절이 돌아온다
- 백엔드가 돌아오면 무엇이 살아남나
- 400 은 다시 보내지 않는다
- 재시도에도 끝이 있다
- 4초 장애를 견디는 설정