LabHub
学习 学习路径 课程

OTCA — OpenTelemetry 认证助理

Collector 返回了 200,Span 却哪儿都找不到

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

목표

백엔드가 멈추거나 요청을 거절할 때 컬렉터의 큐·재시도 설정에 따라 호출자가 받는 응답과 내부 텔레메트리 지표가 어떻게 달라지는지 실제로 재고, 짧은 장애를 유실 없이 넘기는 설정을 설계합니다.

왜 중요한가

애플리케이션이 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.txtmissing_component=(오류가 가리키는 없는 구성요소)를 적고, 파이프라인이 정의된 otlphttp/backend 로 내보내도록 고친 /root/otca-export/fixed.yaml 을 만드세요.
  2. /root/otca-export/no-queue.yaml 을 fixed.yaml 에서 만들고 otlphttp/backendsending_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.txtcodes=, accepted_spans=, refused_spans=, send_failed_spans= 로 옮기세요.
  3. /root/otca-export/queue.yaml 에서 sending_queueretry_on_failure 를 켭니다(다른 값은 기본값). 같은 방식(백엔드 down)으로 돌려 /root/otca-export/03-queue.txtcodes=, accepted_spans=, sent_spans=, send_failed_spans= 를 적으세요.
  4. /root/otca-export/small-queue.yamlsending_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.txtcodes=, 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.txtaccepted_spans=, sent_spans=, send_failed_spans= 를 적으세요.
  6. queue.yaml 을 --backend reject(수신기가 HTTP 400 을 돌려줌)로 돌립니다. /root/otca-export/06-permanent.txtcodes=, sent_spans=, send_failed_spans=, dropping_logged=(로그에 Dropping data 가 있었는지 true/false), retried=(수신기가 받은 요청 수 backend_requests 가 요청 5번보다 많았는지 true/false)를 적으세요.
  7. /root/otca-export/short-retry.yamlretry_on_failureinitial_interval: 500ms, max_interval: 500ms, max_elapsed_time: 2s 로 둡니다(큐는 기본값). 백엔드 down, --wait 6 으로 돌려 /root/otca-export/07-give-up.txtaccepted_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 로 먼저 확인하세요.

참고

기동 전에 잡을 수 있었던 오류

python3 /opt/fixtures/otca_backpressure_lab.py init 으로 재료를 만든 뒤 otelcol-contrib validate --config /root/otca-export/broken.yaml 을 실행합니다. /root/otca-export/01-validate.txtmissing_component=(오류가 가리키는 없는 구성요소)를 적고, 파이프라인이 정의된 otlphttp/backend 로 내보내도록 고친 /root/otca-export/fixed.yaml 을 만드세요.

validate 는 컬렉터를 띄우지 않고 설정의 참조 관계를 검사합니다. 파이프라인이 부르는 이름과 exporters 에 정의한 이름을 비교하세요.

큐도 재시도도 없을 때

/root/otca-export/no-queue.yaml 을 fixed.yaml 에서 만들고 otlphttp/backendsending_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.txtcodes=, accepted_spans=, refused_spans=, send_failed_spans= 로 옮기세요.

큐가 없으면 익스포터 호출이 리시버 요청 안에서 동기로 일어납니다. 실패가 어디까지 거슬러 올라가는지 응답 코드로 확인하세요.

200 을 받았는데 전송은 0

/root/otca-export/queue.yaml 에서 sending_queueretry_on_failure 를 켭니다(다른 값은 기본값). 같은 방식(백엔드 down)으로 돌려 /root/otca-export/03-queue.txtcodes=, accepted_spans=, sent_spans=, send_failed_spans= 를 적으세요.

큐가 있으면 리시버는 큐에 넣는 순간 성공을 돌려줍니다. 수락과 전달은 다른 지표입니다.

큐가 차면 거절이 돌아온다

/root/otca-export/small-queue.yamlsending_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.txtcodes=, accepted_spans=, refused_spans=, enqueue_failed_spans=, queue_size= 를 적으세요.

소비자 하나가 첫 배치를 붙잡고 재시도하는 동안 큐에는 두 칸만 있습니다. 요청은 0.2초 간격으로 들어옵니다.

백엔드가 돌아오면 무엇이 살아남나

같은 small-queue.yaml 을 --backend ok --backend-after 2.5 --wait 6 으로 돌립니다(2.5초 뒤 수신기가 뜸). /root/otca-export/05-recover.txtaccepted_spans=, sent_spans=, send_failed_spans= 를 적으세요.

큐에 들어간 것은 재시도로 살아남지만, 큐에 못 들어가 거절된 것은 컬렉터가 가지고 있지 않습니다. 되보내기는 호출자의 몫입니다.

400 은 다시 보내지 않는다

queue.yaml 을 --backend reject(수신기가 HTTP 400 을 돌려줌)로 돌립니다. /root/otca-export/06-permanent.txtcodes=, sent_spans=, send_failed_spans=, dropping_logged=(로그에 Dropping data 가 있었는지 true/false), retried=(수신기가 받은 요청 수 backend_requests 가 요청 5번보다 많았는지 true/false)를 적으세요.

재시도는 일시적인 실패(연결 거부, 503 등)를 위한 장치입니다. 형식이 잘못됐다는 응답은 몇 번을 보내도 같습니다.

재시도에도 끝이 있다

/root/otca-export/short-retry.yamlretry_on_failureinitial_interval: 500ms, max_interval: 500ms, max_elapsed_time: 2s 로 둡니다(큐는 기본값). 백엔드 down, --wait 6 으로 돌려 /root/otca-export/07-give-up.txtaccepted_spans=, sent_spans=, send_failed_spans=, dropping_logged= 를 적으세요.

max_elapsed_time 이 지나면 재시도를 멈추고 그 배치를 버립니다. 호출자는 이미 200 을 받았으므로 유실은 컬렉터 로그와 내부 지표에만 남습니다.

4초 장애를 견디는 설정

/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 로 먼저 확인하세요.

필요한 것은 두 가지입니다 — 장애 동안 들어온 배치를 모두 담을 자리(재시도 중인 배치는 소비자가 붙들고 있으므로 자리는 queue_size 와 num_consumers 를 함께 봅니다), 그리고 백엔드가 돌아온 뒤 기다림 시간 안에 첫 재시도가 오는 간격. 기본 첫 재시도 간격을 문서에서 확인하세요.