Rastreamento distribuído com Spring Cloud Sleuth e Cloud Trace

1. Visão geral

O rastreamento distribuído é importante para gerar insights e observabilidade em uma arquitetura de microsserviços com várias camadas. Quando há chamadas de serviço a serviço encadeadas, do serviço A ao serviço B ao serviço C, é importante entender que elas foram bem-sucedidas e também a latência em todas as etapas.

No Spring Boot, você pode usar o Spring Cloud Sleuth para adicionar com facilidade 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 trace sem precisar gerenciar sua própria instância ou armazenamento do Zipkin. O Cloud Trace também pode produzir relatórios de distribuição de latência e detectar automaticamente regressões de desempenho.

Há duas opções para usar o Cloud Trace em um aplicativo Spring Boot:

  1. Use um proxy 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ê aprenderá a criar um novo aplicativo Spring Boot e a usar o Spring Cloud GCP Trace para fazer o 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 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

É possível operar remotamente o Google Cloud e o Kubernetes usando um laptop, mas neste codelab vamos usar o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.

Ativar o Cloud Shell

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

55efc1aaa7a4d3ad.png

Se você estiver iniciando o Cloud Shell pela primeira vez, verá uma tela intermediária com a descrição dele. Se aparecer uma tela intermediária, clique em Continuar.

9c92662c6a846a5c.png

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

9f0e51b578fecce5.png

Essa máquina virtual tem 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. Grande parte do trabalho neste codelab, se não todo, pode ser feito em um navegador.

Depois de se conectar ao Cloud Shell, você verá sua autenticação e o projeto estará 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 seguinte comando no Cloud Shell para confirmar que 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, você poderá usar 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

É possível 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

Após uma breve espera, você verá o resultado:

6793a3339447cbb5.png

No Cloud Shell, você também verá as mensagens de registro com o ID do trace e o ID do período:

18d597c388de1ba.png

4. Como usar o Cloud Trace

Ativar a API Cloud Trace

Ative a API Cloud Trace antes de usar o Cloud Trace para armazenar seus dados de trace. Para ativar a API, execute:

$ gcloud services enable cloudtrace.googleapis.com

Configurar a credencial padrão do aplicativo

Neste laboratório, você vai precisar configurar uma credencial padrão do aplicativo. Essa credencial será selecionada automaticamente pela ativação do Spring Cloud GCP Trace.

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 depois 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 Spring Cloud GCP Trace

Neste serviço, já usamos o Spring Cloud Sleuth para rastreamento. Vamos adicionar o inicializador 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 faz amostragem de todas as solicitações. Para facilitar um pouco o teste, aumente a taxa de amostragem para 100% em application.properties, garantindo que os dados de rastreamento sejam mostrados, além de ignorar alguns URLs que não são importantes para nós:

$ 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 visualizá-lo:

$ 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 os dados de trace e os envia uma vez a cada 10 segundos ou quando um número mínimo de dados de trace é recebido. Isso é configurável, e você pode consultar a documentação de referência do Spring Cloud GCP Trace para mais informações.

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

$ curl localhost:8080

No console do Cloud, acesse OperaçõesTraceLista de traces

be48cb0f99b5f7c2.png

Na parte de cima, reduza o período para uma hora. Por padrão, a opção Atualizar automaticamente fica ativada. Assim que os dados de trace chegam, eles devem aparecer no console.

3522eef823df39d8.png

Os dados de rastreamento devem aparecer em cerca de 30 segundos.

9628f6e1d2e75b05.png

Clique no ponto azul para conferir 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 detetive para coletar amostras 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 estiver em execução, volte para a primeira janela de sessão do Cloud Shell e modifique 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(), chame o serviço de reunião.

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

Em ambas as janelas de sessão, você verá as mensagens de registro com o ID do Trace propagado de um serviço para outro.

Na lista de traces do Cloud Trace, você verá o segundo trace:

13490977f1638702.png

Clique no novo ponto azul e confira os detalhes do trace:

ca69ef9cdd13d4aa.png

Também é possível clicar em qualquer período neste diagrama para conferir os detalhes dele.

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

Quando você usa o Cloud Trace como armazenamento de dados de trace, ele pode utilizar os dados para criar um relatório de distribuição de latência. Você precisará de mais de 100 traces para criar o relatório desta forma:

c8713f3d9e51dc25.png

Para executar as mais de 100 solicitações, use 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 no Relatório de análise.

8. Resumo

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

9. Parabéns!

Você aprendeu a criar seu primeiro aplicativo da Web no App Engine.

Saiba mais

Licença

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