Rastreamento distribuído com Spring Cloud Sleuth e Cloud Trace

1. Visão geral

O rastreamento distribuído é importante para ganhar insights e observabilidade em uma arquitetura de microsserviços de várias camadas. Quando você tem chamadas encadeadas de serviço para serviço, do serviço A para o serviço B e para o serviço C, é importante entender se as chamadas foram bem-sucedidas e também a latência em cada etapa.

No Spring Boot, é possível usar o Spring Cloud Sleuth para adicionar sem problemas a instrumentação de rastreamento distribuído ao aplicativo. Por padrão, ele pode encaminhar os dados de rastreamento para o Zipkin.

O Google Cloud Platform tem o Cloud Trace, um serviço gerenciado que permite armazenar dados de rastreamento sem precisar gerenciar sua própria instância do Zipkin nem o armazenamento. O Cloud Trace também pode gerar relatórios de distribuição de latência e detectar automaticamente regressões de desempenho.

Você tem duas opções para usar o Cloud Trace em um aplicativo Spring Boot:

  1. Use um proxy do Zipkin do Stackdriver Trace e configure o Spring Cloud Sleuth para usar esse proxy como o endpoint do Zipkin.
  2. Ou use o Spring Cloud GCP Trace, que se integra perfeitamente ao Spring Cloud Sleuth e encaminha os dados de rastreamento diretamente para o Cloud Trace.

Neste codelab, você vai aprender a criar um novo aplicativo Spring Boot e usar o Spring Cloud GCP Trace para rastreamento distribuído.

O que você vai aprender

  • Como criar um aplicativo Java do Spring Boot e configurar o Cloud Trace.

O que é necessário

  • Um projeto do Google Cloud Platform
  • Um navegador, como o Chrome ou o Firefox
  • Conhecer os editores de texto padrão do Linux, como vim, emacs ou nano

Como você vai usar este tutorial?

Apenas leitura Leitura e exercícios

Como você classificaria sua experiência com a criação de apps da Web em HTML/CSS?

Iniciante Intermediário Proficiente

Como você classificaria sua experiência com o uso dos serviços do Google Cloud Platform?

Iniciante Intermediário Proficiente

2. Configuração e requisitos

Configuração de ambiente autoguiada

  1. Faça login no Console do Google Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • O Nome do projeto é o nome de exibição para os participantes do projeto. É uma string de caracteres não usada pelas APIs do Google e pode ser atualizada quando você quiser.
  • O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser mudado após a definição. O console do Cloud gera automaticamente uma string exclusiva. Em geral, não importa o que seja. Na maioria dos codelabs, é necessário fazer referência ao ID do projeto, normalmente identificado como PROJECT_ID. Se você não gostar do ID gerado, crie outro aleatório. Se preferir, teste o seu e confira se ele está disponível. Ele não pode ser mudado após essa etapa e permanece durante o projeto.
  • Para sua informação, há um terceiro valor, um Número do projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
  1. Em seguida, ative o faturamento no console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não vai ser muito cara, se tiver algum custo. Para encerrar os recursos e evitar cobranças além deste tutorial, exclua os recursos criados ou exclua o projeto. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.

Google Cloud Shell

Embora o Google Cloud e o Kubernetes possam ser operados remotamente em um laptop, neste codelab vamos usar o Google Cloud Shell, um ambiente de linha de comando que é executado no Cloud.

Ativar o Cloud Shell

  1. No Console do Cloud, clique em Ativar o Cloud Shell853e55310c205094.png.

55efc1aaa7a4d3ad.png

Se esta for a primeira vez que você inicia o Cloud Shell, uma tela intermediária vai aparecer com a descrição dele. Se isso acontecer, clique em Continuar.

9c92662c6a846a5c.png

Leva apenas alguns instantes para provisionar e se conectar ao Cloud Shell.

9f0e51b578fecce5.png

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Neste codelab, quase todo o trabalho pode ser feito com um navegador.

Depois de se conectar ao Cloud Shell, você vai ver que sua conta já está autenticada e que o projeto está configurado com o ID do seu projeto.

  1. Execute o seguinte comando no Cloud Shell para confirmar se a conta está autenticada:
gcloud auth list

Resposta ao comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Execute o comando a seguir no Cloud Shell para confirmar se o comando gcloud sabe sobre seu projeto:
gcloud config list project

Resposta ao comando

[core]
project = <PROJECT_ID>

Se o projeto não estiver configurado, configure-o usando este comando:

gcloud config set project <PROJECT_ID>

Resposta ao comando

Updated property [core/project].

3. Criar um novo serviço REST do Spring Boot

Depois que o Cloud Shell for iniciado, use a linha de comando para gerar um novo aplicativo Spring Boot com o Spring Initializr:

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d bootVersion=2.7.6 \
  -d dependencies=web,lombok,cloud-gcp,distributed-tracing \
  -d jvmVersion=17 \
  -d type=maven-project \
  -d baseDir=trace-service-one | tar -xzvf - \
  && cd trace-service-one

Crie um novo controlador REST adicionando uma nova classe:

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!";
  }
}

Verifique se você tem a versão correta da JVM para o aplicativo:

$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Você pode iniciar o aplicativo Spring Boot normalmente com o plug-in Spring Boot. Vamos pular os testes deste laboratório:

$ ./mvnw -DskipTests spring-boot:run

Assim que o aplicativo for iniciado, clique no ícone "Visualização da Web" 3a9b40fafa650b2b.png na barra de ferramentas do Cloud Shell e selecione Visualizar na porta 8080.

3aca52f76c6c22a3.png

Depois de alguns instantes, o resultado vai aparecer:

6793a3339447cbb5.png

No Cloud Shell, você também vai encontrar as mensagens de registro com ID de rastreamento e ID de período:

18d597c388de1ba.png

4. Como usar o Cloud Trace

Ativar a API Cloud Trace

Primeiro, ative a API Cloud Trace antes de usar o Cloud Trace para armazenar seus dados de rastreamento. Para ativar a API, execute:

$ gcloud services enable cloudtrace.googleapis.com

Configurar as credenciais padrão do aplicativo

Neste laboratório, você vai precisar configurar uma credencial padrão do aplicativo. Essa credencial será escolhida automaticamente pelo Spring Cloud GCP Trace Starter.

Primeiro, faça login:

$ 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: ...

Clique no link para abrir uma nova guia do navegador e clique em Permitir.

85f500de6f5dc0a8.png

Em seguida, copie e cole o código de verificação de volta no Cloud Shell e pressione Enter. Você verá:

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

Adicionar o Spring Cloud GCP Trace

Neste serviço, já usamos o Spring Cloud Sleuth para rastreamento. Vamos adicionar o iniciador do Spring Cloud GCP Trace para encaminhar os dados ao Cloud Trace.

Adicione a dependência do Spring Cloud GCP Trace:

pom.xml

<project>
  ...
  <dependencies>
    ...
    <!-- Add Cloud Trace Starter -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-trace</artifactId>
    </dependency>
  </dependencies>
  ...
</project>

Por padrão, o Spring Cloud Sleuth não cria amostras de todas as solicitações. Para facilitar um pouco os testes, aumente a taxa de amostragem para 100% em application.properties para garantir que os dados de rastreamento sejam exibidos, além de ignorar alguns URLs que não são relevantes:

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

Execute o aplicativo novamente e use a visualização da Web do Cloud Shell para conferir o aplicativo:

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

Por padrão, o Spring Cloud GCP Trace agrupa dados de rastreamento e os envia a cada 10 segundos ou quando um número mínimo de dados de rastreamento é recebido. Isso é configurável. Consulte a documentação de referência do Spring Cloud GCP Trace para mais informações.

Faça uma solicitação ao serviço:

$ curl localhost:8080

No console do Cloud, navegue até OperaçõesTraceLista de traces.

be48cb0f99b5f7c2.png

Na parte de cima, reduza o período para uma hora. Por padrão, a Recarga automática está ativada. Assim, quando os dados de rastreamento chegarem, eles vão aparecer no console.

3522eef823df39d8.png

Os dados de rastreamento vão aparecer em cerca de 30 segundos.

9628f6e1d2e75b05.png

Clique no ponto azul para ver os detalhes do trace:

ba9051a8d4f3e725.png

Foi bem simples!

5. Criar um segundo aplicativo da Web do Spring Boot

Abra uma nova sessão do Cloud Shell clicando no ícone +:

9799bee5fea95aa6.png

Na nova sessão, crie o segundo aplicativo Spring Boot:

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d bootVersion=2.7.6 \
  -d dependencies=web,lombok,cloud-gcp,distributed-tracing \
  -d jvmVersion=17 \
  -d type=maven-project \
  -d baseDir=trace-service-two | tar -xzvf - \
  && cd trace-service-two

Crie um novo controlador REST adicionando uma nova classe:

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";
  }
}

Adicionar o Spring Cloud GCP Trace ao pom.xml

pom.xml

<project>
  ...
  <dependencies>
    ...
    <!-- Add Cloud Trace starter -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-trace</artifactId>
    </dependency>
  </dependencies>
  ...
</project>

Configure o Sleuth para fazer amostragem de 100% das solicitações:

src/main/resources/application.properties

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

Por fim, inicie o aplicativo Spring Boot na porta 8081 com o plug-in Spring Boot:

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

6. Atualizar o primeiro serviço para consumir o segundo

Enquanto trace-service-two está em execução, volte para a primeira janela da sessão do Cloud Shell e faça uma modificação em trace-service-one.

Primeiro, inicialize um novo bean 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);
        }
}

Em WorkController.meeting(), faça uma chamada para o serviço de reuniões.

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);
  }

  ...
}

Inicie o serviço novamente e acione o endpoint na linha de comando:

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`

# The '&' places the process in the background. Bring it back to the foreground with 'fg'.
$ ./mvnw -DskipTests spring-boot:run &

$ curl localhost:8080

Nas duas janelas de sessão, você vai encontrar as mensagens de registro, com o ID de rastreamento propagado de um serviço para outro.

Na lista de traces do Cloud Trace, o segundo trace vai aparecer:

13490977f1638702.png

Clique no novo ponto azul para ver os detalhes do trace:

ca69ef9cdd13d4aa.png

Você também pode clicar em qualquer período nesse diagrama para ver os detalhes dele.

7. Relatório de performance e distribuição de latência

Quando você usa o Cloud Trace como armazenamento de dados de rastreamento, ele pode usar os dados para criar um relatório de distribuição de latência. Você precisa de mais de 100 rastreamentos para criar o relatório assim:

c8713f3d9e51dc25.png

Você pode executar essas primeiras 100 solicitações ou mais usando o hey, que vem pré-instalado no Cloud Shell.

$ hey localhost:8080 -n 150

Além disso, o Cloud Trace pode detectar automaticamente a regressão de desempenho do mesmo serviço em dois períodos diferentes em Relatório de análise.

8. Resumo

Neste laboratório, você criou dois serviços simples, adicionou rastreamento distribuído com o Spring Cloud Sleuth e usou o Spring Cloud GCP para encaminhar as informações de rastreamento ao Cloud Trace.

9. Parabéns!

Você aprendeu a escrever seu primeiro aplicativo da Web do App Engine.

Saiba mais

Licença

Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.