Spring Boot와 OpenTelemetry로 분산 트레이싱 설정
Spring Boot 애플리케이션에서 OpenTelemetry와 Zipkin을 연동해 분산 트레이싱을 구성하는 방법과 핵심 설정을 정리한 환경
목차
개요
분산 시스템에서 요청 흐름을 추적하면 성능 병목과 장애 원인 파악이 쉬워진다. 이 글은 Spring Boot 기반 서비스에 OpenTelemetry를 적용해 통합적인 분산 트레이싱을 구성하는 과정을 단계별로 정리한다. 초보자도 이해하기 쉽도록 개념과 실전 설정을 함께 다룬다.
사전 준비
아래 항목이 준비되어 있으면 따라하기가 수월하다.
- Java 11 이상
- Spring Boot 2.5 이상 권장
- Maven 또는 Gradle 빌드 도구
- Zipkin 서버(로컬 또는 원격) 또는 OTLP 수집기
개념 요약
OpenTelemetry 역할
OpenTelemetry는 트레이스, 메트릭, 로그 수집을 위한 표준 API와 SDK를 제공한다. 애플리케이션은 SDK로 스팬(span)을 생성하고, 수집기는 이를 외부 저장소(예: Zipkin)로 전송한다.
Spring Boot와의 통합 방식
통합은 크게 자동 계측(auto-instrumentation)과 코드 수준 수동 계측으로 나뉜다. 자동 계측은 런타임 에이전트를 사용해 프레임워크 레벨을 자동으로 계측하고, 수동 방식은 애플리케이션 코드에서 명시적으로 스팬을 만들거나 Context 전파를 처리한다.
설정 단계
1. 의존성 추가 (Maven 예제)
Spring Boot에 OpenTelemetry SDK와 Zipkin exporter를 추가한다. 아래는 간단한 Maven 의존성 예시다.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.26.0</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
<version>1.26.0</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-zipkin</artifactId>
<version>1.26.0</version>
</dependency>
버전은 안정화된 최신 버전을 확인해 사용한다.
2. 기본 SDK 구성
Spring Boot 애플리케이션 시작 시 OpenTelemetry SDK와 Zipkin Exporter를 등록한다. 예시는 Java 설정 클래스다.
package com.example.tracing;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class OtelConfig {
@Bean
public Tracer tracer() {
ZipkinSpanExporter zipkinExporter = ZipkinSpanExporter.builder()
.setEndpoint("http://localhost:9411/api/v2/spans")
.build();
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.setSampler(Sampler.traceIdRatioBased(1.0))
.addSpanProcessor(BatchSpanProcessor.builder(zipkinExporter).build())
.build();
return io.opentelemetry.api.GlobalOpenTelemetry.builder()
.setTracerProvider(tracerProvider)
.build()
.getTracer("com.example.tracing");
}
}
3. 프레임워크 계측
Spring MVC, WebFlux, RestTemplate, WebClient 등 주요 컴포넌트는 자동 계측 라이브러리를 사용하면 손쉽게 추적된다. 수동 계측이 필요한 경우 Tracer를 주입받아 스팬을 생성한다.
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
private final Tracer tracer;
public DemoController(Tracer tracer) {
this.tracer = tracer;
}
@GetMapping("/hello")
public String hello() {
Span span = tracer.spanBuilder("hello-handler").startSpan();
try {
// 비즈니스 로직
return "hello";
} finally {
span.end();
}
}
}
Zipkin으로 전송 확인
Zipkin 서버를 로컬에서 실행한 뒤 브라우저로 http://localhost:9411 을 열면 스팬이 수신되는지 확인할 수 있다. 스팬이 보이지 않으면 exporter endpoint와 네트워크 설정을 점검한다.
검증과 문제 해결
- 로그: OpenTelemetry SDK와 exporter의 로그 수준을 DEBUG로 올려 초기화 문제를 확인한다.
- Context 전파: 비동기 처리(CompletableFuture, Reactor 등)는 Context 전파 처리가 필요하다.
- 샘플링: 샘플링 비율이 낮으면 스팬이 수집되지 않으므로 개발 환경에서는 1.0을 사용해 확인한다.
권장 설정과 운영 고려사항
- 프로덕션에서는 OTLP 게이트웨이를 통해 중앙 수집기를 두고 Zipkin 또는 Jaeger로 전달한다.
- 샘플링 정책을 트래픽과 비용에 맞춰 조정한다.
- 메트릭과 로그를 결합해 종합적인 관찰성(observability)을 확보한다.
마무리
이 글에서는 Spring Boot에서 OpenTelemetry를 이용해 분산 트레이싱을 구성하는 핵심 절차를 다뤘다. opentelemetry spring boot 설정과 spring boot distributed tracing, zipkin opentelemetry spring boot 같은 키워드를 중심으로 실제 코드와 설정 예시를 제공해 초기 적용을 돕는다. 필요한 경우 자동 계측 에이전트 도입과 OTLP 기반 설계로 확장하면 운영 환경에서 더 안정적인 추적이 가능하다.