MSA를 위한 OpenTelemetry 도입
1. 왜 OpenTelemetry인가?
마이크로서비스 아키텍처(MSA)로 전환하면서 시스템은 유연해졌지만, 운영 복잡도는 기하급수적으로 증가했다. 서비스 간의 호출 관계가 복잡해지면서 "도대체 어디서 에러가 난 거야?", "어느 구간이 느린 거야?" 를 파악하기가 매우 어려워졌다.
기존의 단순 로깅만으로는 분산된 트랜잭션을 추적하기 어렵다고 판단하여, 벤더 중립적이고 표준화된 OpenTelemetry(OTel) 를 도입하여 관측성을 확보하기로 결정했다.
2. OpenTelemetry란?
OpenTelemetry는 클라우드 네이티브 소프트웨어의 성능과 동작을 분석하기 위해 Trace(트레이싱), Metric(메트릭), Log(로그) 데이터를 생성, 수집, 내보내는 오픈소스 표준 프레임워크다.
핵심 구성 요소
OTel SDK
- 애플리케이션 내부에서 Trace / Metric / Log를 생성하고 처리하는 라이브러리
- Gradle 또는 Maven 등의 빌드 도구를 통해 관련 의존성을 추가해서 간단하게 사용 가능

OTel Collector
- 단순히 트레이스만 받아서 넘기는 애? ❌
- 앱, 에이전트, 기존 시스템 등 여러 소스에서 받은 Trace / Metric / Log 데이터를 가공, 필터링, 변환하고, Tempo · Jaeger · Prometheus 등의 백엔드로 중계하는 중간 처리기

Exporter
- Collector 안에 존재하며 데이터를 외부 저장소로 전달하는 역할을 하는 모듈
- SpanData를 최종 백엔드로 내보내는 컴포넌트
- OTLP, Jaeger, Zipkin, Prometheus 포맷 지원
- gRPC / HTTP 기반 전송 방식 선택 가능

3. 아키텍처 구성
프로젝트에서는 다음과 같은 파이프라인을 구축했다.
App(Spring Boot) ➡ OTel Collector ➡ Grafana Tempo (Tracing Backend)
- Application: Java Agent를 사용하여 코드 수정 없이 자동 계측(Auto-Instrumentation) 적용
- Collector: 중앙에서 데이터를 받아 필터링 후 저장소로 전송
- Visualization: Grafana와 Tempo를 연동하여 시각화

4. Hands-on
4-1. Spring Boot 설정
별도의 코드 수정 없이 opentelemetry-javaagent.jar를 사용하여 실행 시점에 에이전트를 붙였다.
java -javaagent:path/to/opentelemetry-javaagent.jar \
-Dotel.service.name=my-service \
-Dotel.exporter.otlp.endpoint=http://otel-collector:4317 \
-jar my-app.jar
Spring Boot 마이크로서비스 2개
order-service: 주문 요청 처리 및 결제 호출
payment-service: 결제 응답 처리 (응답 지연 시뮬레이션 포함)
PostgreSQL: 재고 및 주문 저장용 DB
OpenTelemetry Collector: 데이터 수집 및 처리
Tempo (Grafana): 트레이스 저장소
Grafana: 트레이스 시각화 도구
▲ 아키텍쳐
4-2. OTel Collector 설정 (otel-collector-config.yaml)
Collector는 데이터를 받아(Receiver), 처리하고(Processor), 내보내는(Exporter) 파이프라인으로 구성된다.
receivers:
otlp:
protocols:
grpc:
http:
exporters:
otlp:
endpoint: "tempo:4317" # Tempo 백엔드 주소
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
5. 성과
- 가시성 확보: 분산 트레이싱을 통해 서비스 간 호출 흐름을 한눈에 파악 가능
- MTTR 단축: 장애 발생 시 문제 구간(Root Cause)을 찾는 시간이 줄었다
6. 마치며
MSA 환경에서 로그만으로 디버깅하는 건 솔직히 한계가 있다. 서비스 A의 로그와 서비스 B의 로그를 따로 뒤지며 연결하다 보면 시간이 어디 갔는지 모른다.
OTel 붙이고 나서 달라진 건 하나다. 장애가 나면 Grafana Tempo에서 TraceID 하나 따라가면 어느 서비스, 어느 구간에서 얼마나 걸렸는지 바로 나온다.