[Zipkin] 사용법 가이드 - MSA 요청추적 (springboot/ sleuth/ grpc/ http)
tracing이 필요한 이유
Monolithic 시스템의 경우 클라이언트의 요청을 받으면 하나의 스레드에서 모든 요청을 실행하므로 로그를 확인하기 쉽다는 장점이 있습니다.
그에 반해 MSA의 경우에는 각 서비스의 복잡도가 낮아지고 역할 분담이 용이하지만 클라이언트의 요청을 받았을 때 여러 개의 마이크로 서비스 간에 통신이 발생해 로그를 확인하기 어려운 문제가 있습니다.
이를 해결하기 위한 어플리케이션 간 분산 추적을 위한 표준이 OpenTracing이며, 대표적은 구현체는 zipkin과 jaeger가 있습니다.
클라이언트가 서버로 호출한 하나의 호출을 Trace라고 했을 때, 서비스 컴포넌트간의 호출을 Span이라고 한다.각 서비스 컴포넌트들은 하나의 클라이언트 호출을 추적하기 위해서 같은 Trace Id를 사용하고,
각 서비스간의 호출은 각각 다른 SpanId를 사용합니다. 이렇게 함으로써 전체 트렌젝션 시간을 Trace로 추적이 가능하고, 각 서비스별 구간 시간은 Span으로 추적할 수 있습니다.
개발환경
- spring-boot 2.5.4
- spring-cloud-sleuth
- spring-cloud-sleuth-zipkin
- grpc, http
예제코드는 아래 github에서 확인할수 있습니다.
https://github.com/HyeonGuJ/spring-boot-sleuth-zipkin-grpc-sample
적용하기
촤상위 build.gradle에 의존성 추가
build.gradle
1 | buildscript { |
각 서비스의 application.yml에 zipkin collector 정보 추가
본 예제에서는 zipkin collector server를 9411 port로 설정했다고 가정합니다.
1 | #application.yml |
grpc 서비스들 셋팅하기
spring-cloud-sleuth 의 문서를 기반으로 구현했습니다.
https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/integrations.html#sleuth-rpc-grpc-variant1-integration
grpc server
build.gradle에 의존성을 추가
1 | dependencies { |
application.yml 에 grpc.port를 설정해줍니다
1 | grpc: |
HelloService.proto 를 미리 작성했습니다.
build 후 생성된 소스코드를 사용할수 있는 상태임을 가정합니다.
요청시 처리해야할 로직을 구현하고 @GRpcService
를 통해 노출 할 수 있습니다
1 | //HelloService.java |
grpc client
서버측과 마찬가지로 build.gradle 을 준비합니다(동일하게 셋팅, 예제 생략)
client에서는 server측과 연동하기위해 channel을 열고, stub을 생성후 request를 전송해야합니다.
channel을 열고 stub을 생성성하는 예제입니다.
1 | //GrpcClientConfig.java |
주의
ManagedChannel 을 생성할때 반드시 SpringAwareManagedChannelBuilder로 해야합니다.
SpringAwareManagedChannelBuilder로 생성해야만 Spring에서 grpc 를 inject 할 수 있습니다.
그렇지 않으면 trace id가 전달되지 않습니다. (경험담)
https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/integrations.html#sleuth-rpc-grpc-variant1-client-integration
test
구조
외부 요청을 받는 public 서버가있고, 내부적으로 private, grpcClient를 호출
grpcClient는 http를통해 요청을받고, grpc로 grpcServer와 통신합니다
이 서버들은 모두 zipkin collector server로 데이터를 전송합니다
(출처 zipkin 공식 홈페이지 : https://zipkin.io/pages/architecture.html)
자세한 실행방법은 github - readme.md 를 참고하세요
https://github.com/HyeonGuJ/spring-boot-sleuth-zipkin-grpc-sample
logs
로그상에 trace id가 모두 동일하게 잡히고, span id 는 다르게 보이는것을 확인 할 수 있습니다.
zipkin 에서 확인하기
필자는 docker를 이용해 zipkin을 실행했으며 별도의 설정을 하지않아도 dashboard를 제공하기때문에 이를 통해 확인했습니다.
1 | docker run -d -p 9411:9411 openzipkin/zipkin |
http://localhost:9411/zipkin/traces/{traceId}
위와같이 성공적으로 나오는 모습을 확인 할 수 있었다.
비동기 요청의 경우 아래와같이 동시에 실행되는것 또한 볼 수 있다