마이크로서비스 아키텍처 · 분산 추적과 상관관계 ID · 실습
상관관계 ID 전파 검증하기
목표
W3C traceparent 를 손으로 만들어 3단 서비스 체인에 전파하고, 로그를 트레이스 ID 로 조인해 요청 하나의 경로를 복원한다.
왜 중요한가
분산 추적을 "세 번째 신호라서 필요하다"고 설명하면 도입이 실패합니다. 정확히 어떤 질문에 답하는지를 알아야 합니다. 열 개 서비스의 p99 가 전부 정상인데 사용자 화면은 2초 걸리는 상황 — 여기서 메트릭은 원리적으로 무력합니다. 집계값이라 개별 요청의 경로를 복원할 수 없기 때문입니다. 한 요청에서 4ms 짜리 쿼리가 340번 실행되는 N+1 문제도 메트릭에는 절대 보이지 않습니다. 개별 쿼리가 빠르기 때문입니다. 이 실습은 SDK 없이 헤더 세 조각만으로 그 경로를 복원해 봄으로써, 나중에 OpenTelemetry 를 붙일 때 무엇이 실제로 일어나는지 알고 붙이게 만듭니다.
단계
1. /opt/app/chain.py 로 게이트웨이(8120), 주문(8121), 재고(8122) 세 서비스를 띄운다. GET http://127.0.0.1:8120/order 가 200 을 준다.
2. /root/trace/gen.py 로 traceparent 를 만들어 /root/trace/tp.txt 에 한 줄 저장한다. 00-<32hex>-<16hex>-01 형식이어야 한다.
3. 그 헤더로 게이트웨이를 호출한다. 세 서비스가 각각 /root/trace/svc-<이름>.log 에 trace_id=<값> 을 남기고 세 값이 모두 같아야 한다.
4. 각 로그에 span_id=<16hex> 와 parent_span_id=<16hex> 도 남긴다. 세 서비스의 span_id 는 서로 달라야 한다.
5. /root/trace/join.sh 로 세 로그에서 같은 trace_id 의 줄만 뽑아 /root/trace/joined.log 에 시각 순으로 3줄 남긴다.
6. /opt/app/brokenchain.sh 를 실행하면 8123/8124/8125 에 두 번째 체인이 뜨고 그중 한 서비스가 헤더를 버린다. 각 서비스는 /root/trace/broken-<이름>.log 에 svc=<이름> in_trace=<값> out_trace=<값> 을 남긴다. 들어온 트레이스 ID 와 내보낸 트레이스 ID 가 다른 서비스를 찾아 그 이름을 /root/trace/broken.txt 에 한 줄로 적는다.
7. /root/trace/selftime.txt 에 slowest=<서비스명> total_ms=<정수> 와 self_ms=<정수> 두 줄을 적는다. self 는 전체에서 자식 구간을 뺀 값이다.
참고
- traceparent 형식:
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01 - 트레이스 ID 는 요청 전체에서 같고, 스팬 ID 는 홉마다 바뀝니다.
- 전파가 끊기는 네 곳: 자체 HTTP 클라이언트, 스레드 풀 전달, 메시지 큐, 헤더를 지우는 프록시.
- 흔한 실수: 트레이스 ID 를 대문자 16진수로 만드는 것 — 명세는 소문자입니다.
단계 7개
- 3단 체인 서비스 띄우기
- traceparent 헤더 만들기
- 끝단까지 같은 트레이스 ID 전달하기
- 홉마다 스팬 ID 바꾸기
- 세 로그를 트레이스 ID 로 조인하기
- 전파가 끊긴 서비스 찾기
- 자체 소요 시간 계산하기