[Spring Cloud] MSA : (10) 분산 추적 : Zipkin & Spring Cloud Sleuth
마이크로서비스 환경에서는 하나의 요청이 여러 서비스를 거쳐 처리되기 때문에, 특정 서비스에서의 지연이나 장애가 전체 응답 속도에 영향을 주는 경우가 많다.
분산 시스템의 관점에서 보면, 장애의 원인을 빠르게 식별하고 정확히 진단할 수 있는 능력이 곧 운영 안정성과 직결된다. 어디에서 병목이 발생했는지, 어떤 서비스 호출에서 예외가 발생했는지를 파악하기 어려운 구조인 만큼 투명한 추적이 중요해진다.
이때 사용하는 도구가 바로 Zipkin이다. Zipkin은 마이크로서비스 간의 호출 흐름을 시각화하고, 트랜잭션별로 어느 지점에서 얼마만큼의 시간이 소요되었는지를 추적할 수 있도록 도와준다.
이번 포스팅에서는 Zipkin을 활용한 분산 추적의 기본 개념과 Spring 애플리케이션에 적용하는 방법을 소개하고자 한다.
Zipkin
Zipkin은 Twitter에서 시작된 오픈소스로, 분산 환경에서의 트레이싱 데이터 수집 및 추적을 위한 경량 추적 시스템이다.
마이크로서비스 아키텍처에서는 하나의 요청이 여러 서비스를 거치기 때문에, 전체 요청 흐름을 이해하고 병목 구간이나 실패 지점을 파악하기 위해 트레이싱 시스템이 필요하다.
핵심 개념
- Span : 하나의 요청 내에서 수행되는 작업 단위로, 시작 시각과 종료 시각, 수행된 서비스/메서드 등의 정보를 담는다.
예: A 서비스의 컨트롤러 호출, B 서비스의 DB 조회 등 각각 하나의 Span으로 기록. - Trace : 여러 개의 Span으로 구성된 하나의 요청 단위의 트랜잭션.
계층 구조(Tree 구조)로 각 Span들이 부모-자식 관계로 연결되며, 공통된 Trace ID를 공유한다. - Trace ID / Span ID : 하나의 요청 흐름(Trace)에 고유한 ID가 부여되며, 각 작업(Span)에도 별도의 ID가 존재한다. 이를 기반으로 Zipkin은 전체 요청의 흐름을 시각화할 수 있다.
하나의 요청은 하나의 Trace ID(X)를 공유하며, 각 서비스 간 호출 또는 내부 처리를 위한 Span ID는 각각 새롭게 부여된다.
- Trace ID는 하나의 전체 요청 흐름(트랜잭션)을 식별하는 고유 ID
- Span ID는 하나의 작업(서비스 내 처리 단위)을 식별하며, Trace ID에 포함된 개별 단계
- 서비스 간 요청이 전달될 때 Span이 생성되고, Trace ID는 그대로 전달되며 Span ID는 새로 부여된다.
Service 1
- 클라이언트가 최초로 Service 1에 요청할 때는 Trace ID와 Span ID가 없다.
- 새로운 Trace ID(X)와 Span ID(A)를 생성한다.
- Service 2로 요청을 보낼 때, 기존 Trace ID(X)는 유지되고 새로운 Span ID(B)가 생성된다.
Service 2
- 요청을 수신하면서 Trace ID(X), Span ID(B)를 사용하고, 자체 로직 처리용으로 새로운 Span ID(C)를 생성한다.
- Service 3으로 요청을 보낼 때, Trace ID(X)는 유지되며 새로운 Span ID(D)가 생성된다.
Service 3
- 요청을 수신하면서 Span ID(D)를 사용하고, 내부 처리용으로 새로운 Span ID(E)를 생성한다.
- Service 4로 요청을 보낼 때, Trace ID(X)는 유지되고 새로운 Span ID(F)가 생성된다.
Service 4
- 요청을 수신하면서 Span ID(F)를 사용하고, 자체 처리용으로 새로운 Span ID(G)를 생성한다.
Zipkin 서버 설치
Zipkin을 사용하려면 Zipkin 서버가 필요하다. 이것은 각 서비스에서 발생한 Trace/Span 데이터를 수집하는 저장소 역할을 하며 시각화 UI를 포함하여 추적 데이터를 조회할 수 있는 다양한 API를 제공한다.
▶ Docker를 사용한 Zipkin 설치
docker run -d -p 9411:9411 openzipkin/zipkin
Zipkin 설치 방법
https://zipkin.io/pages/quickstart
Quickstart · OpenZipkin
Quickstart In this section we’ll walk through building and starting an instance of Zipkin for checking out Zipkin locally. There are three options: using Java, Docker or running from source. If you are familiar with Docker, this is the preferred method t
zipkin.io
Spring Cloud Sleuth
- Spring Cloud Sleuth는 Spring 기반 애플리케이션에서 Zipkin과 쉽게 연동할 수 있도록 도와주는 라이브러리다.
- 각 요청마다 자동으로 Trace ID와 Span ID를 생성 및 전달하며, 로그에도 함께 기록되도록 설정할 수 있다.
- 내부적으로 HTTP 요청/응답, 메시지 큐, FeignClient 등의 호출에 트레이싱 정보를 삽입하여 전체 경로를 추적 가능하게 만든다.
우리가 추적해보려는 상황은 회원 조회 시의 분산 시스템(User Service와 Order Service) 간의 통신 시의 Trace이다.
따라서 분산 시스템 간의 추적(Trace)를 활성화하기 위해서 사용하려는 서비스들 (User-Service와 Order-Service)에 각각 Zipkin과 관련된 의존성을 추가하고, 환경변수를 설정해주었다.
▶ pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
▶ application.yml
spring:
application:
name: user-service
zipkin:
base-url: http://localhost:9411
enabled: true
sleuth:
sampler:
probability: 1.0
- spring.application.name : 서비스 이름을 지정하며, Zipkin UI에서 어떤 서비스가 데이터를 보냈는지 식별하는 데 사용
- spring.zipkin.base-url: Zipkin 서버의 주소를 지정
- spring.zipkin.enabled: Zipkin 연동 기능을 활성화
- spring.sleuth.sampler.probability: 1.0은 전체 요청의 100%를 추적 대상으로 설정하며, 모든 요청에 대해 Trace/Span ID가 생성되고 Zipkin에 전송되도록 한다.
Zipkin UI 살펴보기
- Zipkin UI는 브라우저에서 확인 가능한 분산 추적 시각화 도구로 지원된다. Zipkin 서버를 실행하면 기본적으로 http://localhost:9411 주소에서 접속할 수 있다.
- 각 요청(Trace)을 트랜잭션 단위로 트리 구조로 시각화해 보여준다. 요청이 거친 서비스와 각 서비스 내의 처리 단계(Span)를 계층적으로 확인할 수 있다.
- Trace ID, 서비스 이름, 경로, 처리 시간 등을 기반으로 요청을 검색할 수 있다.
- 요청의 세부 정보를 클릭하면 HTTP 메서드, 호출 경로, 컨트롤러 클래스, 메서드 이름, 클라이언트 IP 등의 태그 정보를 볼 수 있다.
- Span 간 시작 시점, 종료 시점, 소요 시간 등을 시각화하여 병목이나 지연 발생 구간을 쉽게 파악할 수 있다.
- 에러가 발생한 Span은 빨간색 아이콘으로 표시되어, 문제 지점을 빠르게 식별할 수 있다.
Trace ID와 Span ID 살펴보기
Sleuth 활성화를 하면 Trace ID, Span ID가 Spring Log에 자동으로 포함되기 때문에 Application 상에서도 Span과 Trace를 추적할 수 있다.
- 로그에 각 마이크로서비스(user-service, order-service)별 Trace ID와 Span ID가 출력되고 있다.
- user-service와 order-service가 같은 Trace ID(cf4a...)를 공유하고 있어, 하나의 요청 흐름이라는 것을 알 수 있다.
- 첫 번째 요청에서는 Trace ID와 Span ID가 동일하다 → 이는 루트 Span(요청의 시작점)이라는 의미다.
- 두 번째 요청에서는 Trace ID는 같지만 Span ID가 변경되었음을 알 수 있다. → 요청 흐름 내에서 각 작업(Span)이 독립적으로 기록된다는 것이다.
- 요청을 한 번 더 해보았을 때에는 다른 Trace ID(031b...)가 부여되는 것을 확인할 수 있다.
- 이것은 요청마다 고유한 Trace ID가 부여된다는 것을 확인할 수 있다.
정리
마이크로서비스 아키텍처에서는 하나의 요청이 여러 서비스를 거치며 처리되기 때문에, 단일 로그만으로 전체 흐름을 파악하기 어렵다. 이런 구조에서는 장애 원인이나 병목 지점을 추적하는 것이 매우 까다로워진다.
Zipkin은 이러한 분산 환경에서 각 서비스의 호출 관계와 처리 시간을 시각적으로 확인 가능하기 때문에 장애 분석과 성능 튜닝의 도구로 유용하게 사용할 수 있다.
사용하기 좋은 유스케이스
- 장애 발생 시 원인 서비스 파악이 어려운 경우
- 전체 요청이 지연되지만, 어느 단계에서 느린지 알 수 없을 때
- 여러 서비스가 얽힌 복잡한 호출 관계를 추적하고 싶을 때
References
https://docs.spring.io/spring-cloud-sleuth/docs/2.2.5.RELEASE/reference/html/
Spring Cloud Sleuth
Spring Cloud Sleuth automatically instruments all your Spring applications, so you should not have to do anything to activate it. The instrumentation is added by using a variety of technologies according to the stack that is available. For example, for a s
docs.spring.io
Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) 강의 | Dowon Lee - 인프런
Dowon Lee | , 클라우드 네이티브 아키텍처를 구축하고, 마이크로서비스 앱 개발에 도전하세요! 🚧 [사진] IT 시스템에는 매년 수많은 기술이 생겨나고, 사라지고 있습니다. 새롭게 출시된 개념이나
www.inflearn.com
'Backend > Spring Cloud MSA' 카테고리의 다른 글
[Spring Cloud] MSA : (9) 분산 시스템의 장애 격리 : CircuitBreaker & Resilience4j (4) | 2025.05.03 |
---|---|
[Spring Cloud] MSA : (8) Apache Kafka 연결 : 데이터베이스 동기화 (1) | 2024.01.07 |
[Spring Cloud] MSA : (7) Apache Kafka 연결 : 서비스 간 비동기 통신 (1) | 2024.01.06 |
[Spring Cloud] MSA : (6) 서비스 간 동기적 통신 : RestTemplate과 FeignClient (1) | 2023.12.04 |
[Spring Cloud] MSA: (5) RabbitMQ와 Spring Cloud Bus로 Config 구성정보 동기화하기 (1) | 2023.11.26 |