1. Zipkin?
MSA를 공부하면서 zipkin을 접했었는데, 이번에 zipkin을 적용할 기회가 생겼다.
공식 사이트에 따르면, zipkin은 분산 추적 시스템(distributed tracing system)이라고 설명하고 있다. 분산 추적이라는 말에 걸맞게 서로 다른 애플리케이션 간에 통신하는 환경에서 주로 사용하는데, 최근 MSA가 인기를 끌면서 함께 인기를 얻은 오픈소스로 보인다.
실제로 나온지 10년 가량 된 오픈소스인데, 2015~2016년 경에 spring cloud sleuth에서 zipkin을 지원하기 시작한 후 인기가 급격히 높아졌다.
해당 오픈소스는 트위터에서 개발했으며, HTTP나 Kafka를 통한 데이터 리포트가 가장 널리 사용되는 방법이다. 리포트된 데이터는 기본적으로 zipkin 로컬 메모리에 저장하고, 외부 레파지토리도 사용 가능한데 보통 소규모 시스템에는 mysql, 대규모 시스템에는 cassandra나 elasticSearch를 권장한다고 한다.
2. zipkin기동
기동은 간단하다. docker이미지를 통해 기동할 수도 있고, java8이상을 사용할 경우 executable jar를 이용해 기동할 수도 있다.
이외에도 github의 zipkin source를 클론해와 기동하거나 스프링부트를 통해 zipkin서버를 직접 기동하는 방법도 있다.
2.1. docker기동
docker run -d -p 9411:9411 openzipkin/zipkin
2.2. executable jar기동
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar
위와 같이 기동 후 localhost:9411로 접속하면, 그래서 뭘 어쩌라는건가 싶은 텅 빈 zipkin ui가 나타난다.
위의 그림은 zipkin 공식페이지에서 가져온 다이어그램인데, 그림에서 collector, storage, api, ui를 포함한 기본 zipkin서버를 기동했다고 이해하면 된다.
이걸 위와 같이, reporter를 통해 실제 서비스에 붙여줘야 비로소 트레이싱된 데이터를 정상적으로 확인할 수 있다.
3. Zipkin사용하기
3.1. MSA+zipkin 설정 예제
튜토리얼 을 통해 spring boot msa+zipkin을 적용한 예제를 확인할 수 있다.
service1 -> service2-> service3-> service4를 restTemplate을 통해 호출하는 간단한 예제인데, zipkin을 어떨 때 사용하면 되는지, spring boot환경에서 어떻게 적용하면 되는지 이해하기 좋다.
/foo라는 요청이 있으면 각각의 요청에 trace id 및 span id를 발급한다. service1 -> service2로 옮겨가는 각각의 요청에 따른 id가 span id고, 각각의 span id를묶어 하나의 거래를 이루는데 이를 trace id라고 부른다.
하나의 거래에 대해 가장 처음 발급된 span id = trace id 라고 생각하면 되고, 각각의 요청에 대한 응답을 클라이언트에 보낸 후 비동기로 span을 zipkin collector에 전송하기 때문에 zipkin에서는 오버헤드가 거의 없다고 설명하고 있다.
3.2. zipkin docker예제
또한 openzipkin github에서는 데모 혹은 테스트용으로 활용할 수 있는 도커 예제를 제공한다.
slim버전 외에도 elasticSearch, cassandra, mysql을 적용한 버전, 카프카를 통해 트레이스를 수집하는 버전, 그리고 prometheus와 grafana를 통해 시각화까지 하는 버전 등 다양한 docker compose파일을 제공하는데, 모든 버전이 완전히 잘 되지는 않는다.(…)
그렇지만 prometheus설정 등 충분히 참고할만한 내용이 많다.
4. Camel zipkin?
camel에서는 이러한 zipkin을 확장해 camel의 라우터 간 메시지를 추적할 수 있는 컴포넌트를 제공한다. 그것이 camel zipkin인데, 레퍼런스가 그다지 많지는 않다.
공식 문서에서는 camel 2.18부터 제공하고 있다고는 하나, 실제로 적용해보면 구버전의 경우 트레이스는 되지만 해당 데이터가 로깅이 되질 않아 결국 zipkin ui에서 확인이 불가하다.
그러니 마음편하게 최소 2.21 이상의 camel을 이용하는 것을 추천한다. 아래는 camel zipkin적용 관련 코드이다.
4.1. maven pom.xml
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-zipkin-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-okhttp3</artifactId>
<version>2.14.0</version>
</dependency>
4.2.zipkin tracer
ZipkinTracer zipkin = new ZipkinTracer();
zipkin.setSpanReporter(AsyncReporter.create(OkHttpSender.create("http://127.0.0.1:9411/api/v2/spans")));
zipkin.setIncludeMessageBody(true);
zipkin.setIncludeMessageBodyStreams(true);
zipkin.init(camelContext);
혹은 camel-zipkin-starter를 사용해 적용하는 방법이 있는데(사실 훨씬 간단함), 이는 해당 레파지토리에서 확인 가능하다.
5. 기타 모니터링 오픈소스
추가적으로 zipkin은 prometheus 및 grafana를 활용해 시각화가 가능하다.
zipkin은 기본적으로 모니터링을 위한 메트릭을 제공한다. 이는 프로메테우스를 통해 주기적으로 수집하게 할 수 있고, zipkin 및 프로메테우스는 모두 그라파나에 데이터소스로 등록하여 대시보드로 시각화할 수 있다.
먼저 grafana를 기동한 후, grafana zipkin공식문서를 통해 zipkin을 datasource로 등록한다. 그리고 외부 dashboard사용을 위해 prometheus또한 설치 후 datasource로 등록한 뒤에, grafana zipkin dashboard를 import해주면 된다.
글은 장황하지만 모두 생각보다 쉽게 적용 가능하다. 해당 포스팅의 상세 내용은 차후 별도 적용해 신규 포스팅할 예정이다.