Spring Cloud Sleuth 및 Stackdriver Trace를 사용한 분산 추적

분산 추적은 다중 계층 마이크로서비스 아키텍처에 대한 유용한 정보와 관측 가능성을 얻는 데 중요합니다. 서비스 A에서 서비스 B, 서비스 C로 서비스 간 호출이 연결된 경우 호출이 성공했는지와 각 단계의 지연 시간을 파악하는 것이 중요합니다.

Spring Boot에서는 Spring Cloud Sleuth를 사용하여 분산 추적 계측을 애플리케이션에 원활하게 추가할 수 있습니다. 기본적으로 추적 데이터를 Zipkin으로 전달할 수 있습니다.

Google Cloud Platform에는 자체 Zipkin 인스턴스나 스토리지를 관리하지 않고도 추적 데이터를 저장할 수 있는 관리형 서비스인 Stackdriver Trace가 있습니다. Stackdriver Trace는 지연 시간 분포 보고서를 생성하고 성능 회귀를 자동으로 감지할 수도 있습니다.

Spring Boot 애플리케이션에서 Stackdriver Trace를 사용하는 방법에는 다음 두 가지가 있습니다.

  1. Stackdriver Trace Zipkin 프록시를 사용하고 이 프록시를 Zipkin 엔드포인트로 사용하도록 Spring Cloud Sleuth를 구성하기만 하면 됩니다.
  2. 또는 Spring Cloud Sleuth와 원활하게 통합되고 추적 데이터를 Stackdriver Trace로 직접 전달하는 Spring Cloud GCP Trace를 사용합니다.

이 Codelab에서는 새로운 Spring Boot 애플리케이션을 빌드하고 Spring Cloud GCP Trace를 사용하여 분산 추적하는 방법을 알아봅니다.

학습할 내용

  • Spring Boot Java 애플리케이션을 만들고 Stackdriver Trace를 구성하는 방법

필요한 항목

  • Google Cloud Platform 프로젝트
  • 브라우저(Chrome, Firefox 등)
  • Vim, EMACs, Nano 등의 표준 Linux 텍스트 편집기에 관한 기본 지식

이 튜토리얼을 어떻게 사용하실 계획인가요?

읽기만 할 계획입니다 읽은 다음 연습 활동을 완료할 계획입니다

HTML/CSS 웹 앱 빌드 경험을 평가해 주세요.

초급 중급 고급

귀하의 Google Cloud Platform 서비스 사용 경험을 평가해 주세요.

초급 중급 고급

자습형 환경 설정

아직 Google 계정 (Gmail 또는 Google Apps)이 없으면 계정을 만들어야 합니다. Google Cloud Platform 콘솔 (console.cloud.google.com)에 로그인하고 새 프로젝트를 만듭니다.

Screenshot from 2016-02-10 12:45:26.png

모든 Google Cloud 프로젝트에서 고유한 이름인 프로젝트 ID를 기억하세요(위의 이름은 이미 사용되었으므로 사용할 수 없습니다). 이 ID는 나중에 이 Codelab에서 PROJECT_ID라고 부릅니다.

그런 다음 Google Cloud 리소스를 사용할 수 있도록 Cloud 콘솔에서 결제를 사용 설정해야 합니다.

이 codelab을 실행하는 과정에는 많은 비용이 들지 않지만 더 많은 리소스를 사용하려고 하거나 실행 중일 경우 비용이 더 들 수 있습니다(이 문서 마지막의 '삭제' 섹션 참조).

Google Cloud Platform 신규 사용자는 $300 상당의 무료 체험판을 사용할 수 있습니다.

Google Cloud Shell

Google Cloud 및 Kubernetes를 노트북에서 원격으로 실행할 수 있지만, 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.

Google Cloud Shell 활성화하기

GCP 콘솔에서 오른쪽 상단 툴바의 Cloud Shell 아이콘을 클릭합니다.

그런 다음 'Cloud Shell 시작'을 클릭합니다.

환경을 프로비저닝하고 연결하는 데 몇 분 정도 소요됩니다.

가상 머신은 필요한 모든 개발 도구와 함께 로드됩니다. 영구적인 5GB 홈 디렉토리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 실습에서 대부분의 작업은 브라우저나 Google Chromebook만을 이용하여 수행할 수 있습니다.

Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 PROJECT_ID로 이미 설정된 것을 확인할 수 있습니다.

Cloud Shell에서 다음 명령어를 실행하여 인증되었는지 확인합니다.

gcloud auth list

명령어 결과

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

명령어 결과

[core]
project = <PROJECT_ID>

또는 다음 명령어로 설정할 수 있습니다.

gcloud config set project <PROJECT_ID>

명령어 결과

Updated property [core/project].

Cloud Shell이 실행되면 명령줄을 사용하여 Spring Initializr로 새 Spring Boot 애플리케이션을 생성할 수 있습니다.

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d dependencies=web,lombok,cloud-gcp,cloud-starter-sleuth \
  -d baseDir=trace-service-one | tar -xzvf - \
  && cd trace-service-one

새 클래스를 추가하여 새 REST 컨트롤러를 만듭니다.

src/main/java/com/example/demo/WorkController.java

package com.example.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
@Slf4j
public class WorkController {
  Random r = new Random();

  public void meeting() {
    try {
      log.info("meeting...");
      // Delay for random number of milliseconds.
      Thread.sleep(r.nextInt(500));
    } catch (InterruptedException e) {
    }
  }

  @GetMapping("/")
  public String work() {
    // What is work? Meetings!
    // When you hit this URL, it'll call meetings() 5 times.
    // Each time will have a random delay.
    log.info("starting to work");
    for (int i = 0; i < 5; i++) {
      this.meeting();
    }
    log.info("finished!");
    return "finished work!";
  }
}

Spring Boot 플러그인을 사용하여 Spring Boot 애플리케이션을 정상적으로 시작할 수 있습니다. 이 실습의 테스트는 건너뛰겠습니다.

$ ./mvnw -DskipTests spring-boot:run

애플리케이션이 시작되면 Cloud Shell 툴바에서 웹 미리보기 아이콘 을 클릭하고 포트 8080에서 미리보기를 선택합니다.

잠시 기다리면 결과가 표시됩니다.

Cloud Shell에도 추적 ID와 스팬 ID가 포함된 로그 메시지가 표시됩니다.

Stackdriver Trace API 사용 설정

Stackdriver Trace를 사용하여 추적 데이터를 저장하려면 먼저 Stackdriver Trace API를 사용 설정해야 합니다. API를 사용 설정하려면 API 서비스 → 라이브러리로 이동합니다.

Stackdriver Trace를 검색합니다.

Stackdriver Trace API를 클릭한 다음 아직 사용 설정되어 있지 않으면 사용 설정을 클릭합니다.

애플리케이션 기본 사용자 인증 정보 설정

이 실습에서는 애플리케이션 기본 사용자 인증 정보를 구성해야 합니다. 이 사용자 인증 정보는 Spring Cloud GCP Trace 스타터에 의해 자동으로 선택됩니다.

먼저 로그인합니다.

$ gcloud auth application-default login
You are running on a Google Compute Engine virtual machine.
The service credentials associated with this virtual machine
will automatically be used by Application Default
Credentials, so it is not necessary to use this command.
If you decide to proceed anyway, your user credentials may be visible
to others with access to this virtual machine. Are you sure you want
to authenticate with your personal account?
Do you want to continue (Y/n)? Y

Go to the following link in your browser:
    https://accounts.google.com/o/oauth2/auth...
Enter verification code: ...

링크를 클릭하여 새 브라우저 탭을 열고 허용을 클릭합니다.

그런 다음 인증 코드를 Cloud Shell에 다시 복사하여 붙여넣고 Enter 키를 누릅니다. 다음과 같이 표시됩니다.

Credentials saved to file: [/tmp/tmp.jm9bnQ4R9Q/application_default_credentials.json]
These credentials will be used by any library that requests
Application Default Credentials.

Spring Cloud GCP Trace 추가

이 서비스에서는 이미 추적을 위해 Spring Cloud Sleuth를 사용했습니다. Stackdriver Trace로 데이터를 전달하기 위해 Spring Cloud GCP Trace 시작 프로그램을 추가해 보겠습니다.

Spring Cloud GCP Trace 종속 항목을 추가합니다.

pom.xml

<project>
  ...
  <dependencies>
    ...
    <!-- Add Stackdriver Trace Starter -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-trace</artifactId>
    </dependency>
  </dependencies>
  ...
</project>

기본적으로 Spring Cloud Sleuth는 모든 요청을 샘플링하지 않습니다. 테스트를 좀 더 쉽게 하기 위해 application.properties에서 샘플링 비율을 100% 로 늘려 트레이스 데이터를 확인하고 관심이 없는 일부 URL을 무시합니다.

$ echo "
spring.sleuth.sampler.probability=1.0
spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*)
" > src/main/resources/application.properties

애플리케이션을 다시 실행하고 Cloud Shell 웹 미리보기를 사용하여 애플리케이션을 확인합니다.

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw -DskipTests spring-boot:run

기본적으로 Spring Cloud GCP Trace는 추적 데이터를 일괄 처리하고 10초마다 또는 최소 개수의 추적 데이터가 수신될 때 전송합니다. 이는 구성 가능하며 자세한 내용은 Spring Cloud GCP Trace 참조 문서를 참고하세요.

서비스에 요청합니다.

$ curl localhost:8080

Cloud Console에서 StackdriverTraceTrace 목록으로 이동합니다.

상단에서 기간을 1시간으로 좁힙니다. 기본적으로 자동 새로고침이 사용 설정되어 있습니다. 따라서 트레이스 데이터가 도착하면 콘솔에 표시됩니다.

추적 데이터는 약 30초 후에 표시됩니다.

파란색 점을 클릭하여 추적 세부정보를 확인합니다.

정말 간단하네요.

+ 아이콘을 클릭하여 새 Cloud Shell 세션을 엽니다.

새 세션에서 두 번째 Spring Boot 애플리케이션을 만듭니다.

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d dependencies=web,lombok,cloud-gcp,cloud-starter-sleuth \
  -d baseDir=trace-service-two | tar -xzvf - \
  && cd trace-service-two

새 클래스를 추가하여 새 REST 컨트롤러를 만듭니다.

src/main/java/com/example/demo/MeetingController.java

package com.example.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
@Slf4j
public class MeetingController {
  Random r = new Random();

  @GetMapping("/meet")
  public String meeting() {
    try {
      log.info("meeting...");
      Thread.sleep(r.nextInt(500 - 20 + 1) + 20);
    } catch (InterruptedException e) {
    }
    return "finished meeting";
  }
}

pom.xml에 Spring Cloud GCP Trace 추가

pom.xml

<project>
  ...
  <dependencies>
    ...
    <!-- Add Stackdriver Trace starter -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-trace</artifactId>
    </dependency>
  </dependencies>
  ...
</project>

모든 요청을 샘플링하도록 Sleuth를 구성합니다.

src/main/resources/application.properties

$ echo "
spring.sleuth.sampler.probability=1.0
spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*)
" > src/main/resources/application.properties

마지막으로 Spring Boot 플러그인을 사용하여 포트 8081에서 Spring Boot 애플리케이션을 시작할 수 있습니다.

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw -DskipTests spring-boot:run -Dserver.port=8081

trace-service-two가 실행되는 동안 첫 번째 Cloud Shell 세션 창으로 돌아가서 trace-service-one을 수정합니다.

먼저 새 RestTemplate 빈을 초기화합니다.

src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

...

import org.springframework.web.client.RestTemplate;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {
        @Bean
        public RestTemplate restTemplate() {
                return new RestTemplate();
        }
        
        public static void main(String[] args) {
                SpringApplication.run(DemoApplication.class, args);
        }
}

WorkController.meeting()에서 회의 서비스에 대한 호출을 실행합니다.

src/main/java/com/example/demo/WorkController.java

package com.example.demo;

...
import org.springframework.web.client.RestTemplate;
import org.springframework.beans.factory.annotation.Autowired;

@RestController
@Slf4j
public class WorkController {
  @Autowired
  RestTemplate restTemplate;

  public void meeting() {
    String result = restTemplate.getForObject("http://localhost:8081/meet", String.class);
    log.info(result);
  }

  ...
}

서비스를 다시 시작하고 웹 미리보기에서 엔드포인트를 트리거합니다.

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw -DskipTests spring-boot:run

두 세션 창 모두에서 한 서비스에서 다른 서비스로 전파된 추적 ID와 함께 로그 메시지가 표시됩니다.

Stackdriver Trace의 추적 목록에 두 번째 추적이 표시됩니다.

파란색 점을 클릭하여 트레이스 세부정보를 확인할 수 있습니다.

이 다이어그램에서 스팬을 클릭하여 스팬 세부정보를 볼 수도 있습니다.

Stackdriver Trace를 추적 데이터 저장소로 사용하면 Stackdriver Trace에서 데이터를 사용하여 지연 시간 분포 보고서를 빌드할 수 있습니다. 다음과 같은 보고서를 만들려면 100개가 넘는 트레이스가 필요합니다.

또한 Stackdriver Trace는 분석 보고서에서 서로 다른 두 기간에 걸쳐 동일한 서비스의 성능 회귀를 자동으로 감지할 수 있습니다.

이 실습에서는 간단한 서비스 2개를 만들고 Spring Cloud Sleuth를 사용하여 분산 추적을 추가했으며 Spring Cloud GCP를 사용하여 추적 정보를 Stackdriver Trace로 전달했습니다.

첫 번째 App Engine 웹 애플리케이션을 작성하는 방법을 알아봤습니다.

자세히 알아보기

라이선스

이 작업물은 Creative Commons Attribution 2.0 일반 라이선스에 따라 사용이 허가되었습니다.