Rastreamento distribuído com Spring Cloud Sleuth e Stackdriver Trace

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 seu aplicativo. Por padrão, ele pode encaminhar os dados de rastreamento para o Zipkin.

O Google Cloud Platform tem o Stackdriver 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 Stackdriver 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 Stackdriver 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 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 Stackdriver 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 Stackdriver 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

Configuração de ambiente autoguiada

Se você ainda não tem uma Conta do Google (Gmail ou Google Apps), crie uma. Faça login no Console do Google Cloud Platform (console.cloud.google.com) e crie um projeto:

Captura de tela de 2016-02-10 12:45:26.png

Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID.

Em seguida, ative o faturamento no console do Cloud para usar os recursos do Google Cloud.

A execução por meio deste codelab terá um custo baixo, mas poderá ser mais se você decidir usar mais recursos ou se deixá-los em execução. Consulte a seção "limpeza" no final deste documento.

Novos usuários do Google Cloud Platform têm direito a uma avaliação sem custo financeiro de US$300.

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 Google Cloud Shell

No Console do GCP, clique no ícone do Cloud Shell na barra de ferramentas localizada no canto superior direito:

Em seguida, clique em "Start Cloud Shell":

O provisionamento e a conexão ao ambiente levarão apenas alguns instantes para serem concluídos:

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. Praticamente todo o seu trabalho neste laboratório pode ser feito em um navegador ou no seu Google Chromebook.

Depois de se conectar ao Cloud Shell, sua conta já estará autenticada e o projeto estará configurado com seu PROJECT_ID.

Execute o seguinte comando no Cloud Shell para confirmar se a conta está autenticada:

gcloud auth list

Resposta ao comando

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
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].

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 dependencies=web,lombok,cloud-gcp,cloud-starter-sleuth \
  -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!";
  }
}

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 de Visualização da Web na barra de ferramentas do Cloud Shell e selecione Visualizar na porta 8080.

Depois de uma breve espera, o resultado vai aparecer:

No Cloud Shell, você também vai encontrar as mensagens de registro com ID de rastreamento e ID de extensão:

Ativar a API Stackdriver Trace

Primeiro, ative a API Stackdriver Trace para usar o serviço e armazenar seus dados de rastreamento. Para ativar a API, acesse Serviços de API → Biblioteca.

Pesquise Stackdriver Trace.

Clique em API Stackdriver Trace e em Ativar se ela ainda não estiver ativada.

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.

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 rastreamento do Spring Cloud GCP

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 Stackdriver Trace.

Adicione a dependência do 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>

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é Stackdriver TraceLista de rastreamentos

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

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

Clique no ponto azul para ver os detalhes do trace:

Foi bem simples!

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

Na nova sessão, crie o segundo aplicativo 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

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 Stackdriver Trace starter -->
    <dependency>
      <groupId>org.springframework.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 -Dserver.port=8081

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 visualização da Web:

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

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

Na lista de rastreamentos do Stackdriver Trace, você vai encontrar o segundo rastreamento:

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

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

Quando você usa o Stackdriver 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 um relatório como este:

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

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 Stackdriver Trace.

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.