O Zipkin é um sistema de rastreamento distribuído open source desenvolvido pelo Twitter para monitorar dados em tempo real. Ele agrega informações de monitoramento coletadas de diversos sistemas heterogêneos. Este guia demonstra como instrumentar sua aplicação Java com a biblioteca Brave e enviar dados de rastreamento ao ARMS Tracing Analysis por meio de um endpoint compatível com Zipkin.
Escolha um método de instrumentação
Selecione o método adequado ao seu framework. O Spring Sleuth exige menos configuração e é a opção recomendada para projetos Spring Boot.
|
Método |
Mais indicado para |
Complexidade |
|
Spring Sleuth |
Microsserviços Spring Cloud (recomendado) |
Baixa |
|
Spring 4.0 MVC ou Spring Boot |
Projetos modernos baseados em anotações do Spring |
Média |
|
Spring 2.5 ou 3.0 MVC |
Projetos legados baseados em XML do Spring |
Média |
|
Dubbo |
Aplicações Dubbo RPC |
Média |
|
Instrumentação manual |
Controle total sobre spans e tags |
Alta |
Fluxo de dados
Sua aplicação utiliza a biblioteca Brave para criar spans e enviá-los ao ARMS por meio de um endpoint compatível com Zipkin.

Pré-requisitos
Obtenha um endpoint do Zipkin
Para relatar dados de rastreamento, obtenha um endpoint compatível com Zipkin no console do Tracing Analysis.
Faça login no console do Tracing Analysis.
No painel de navegação à esquerda, clique em Cluster Configurations. Em seguida, clique na aba Access point information.
Na barra de navegação superior, selecione uma região. Na seção Cluster Information, ative a opção Show Token.
Na seção Client, clique em Zipkin.
Copie o endpoint da coluna Related Information.

Se sua aplicação executa em um ambiente de produção da Alibaba Cloud, utilize um ponto de acesso VPC da Alibaba Cloud. Caso contrário, use um endpoint público.
Utilize o endpoint v2, a menos que tenha um motivo específico para usar a versão v1.
Frameworks suportados
A biblioteca Brave oferece instrumentação para os seguintes frameworks Java. Para consultar a lista completa, acesse brave-instrumentation.
Apache HttpClient, Dubbo, gRPC, JAX-RS 2.X, Jersey Server, JMS, Kafka, MySQL, Netty, OkHttp, Servlet, Spark, Spring Boot, Spring MVC
Projeto de demonstração
Há uma demonstração funcional disponível para cada método de instrumentação. Baixe o projeto de demonstração e siga as instruções do arquivo README no diretório correspondente.
|
Método |
Diretório da demonstração |
|
|
Instrumentação manual |
|
|
|
Spring 2.5 ou 3.0 MVC |
|
webmvc25` |
|
Spring 4.0 MVC ou Spring Boot |
|
webmv4` |
|
Dubbo |
|
|
|
Spring Sleuth |
|
Instrumente com Spring Sleuth
O Spring Cloud Sleuth fornece rastreamento distribuído automático para aplicações Spring Boot com configuração mínima. Ele se integra nativamente ao Zipkin para o envio de dados de rastreamento.
Etapa 1: Adicione as dependências
Adicione as seguintes dependências ao seu arquivo pom.xml:
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-okhttp3</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-core</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
Etapa 2: Configure o application.yml
Defina a URL base do Zipkin e a taxa de amostragem. Substitua <endpoint_short> pelo endpoint público que termina com api/v2/spans, obtido na aba Access point information do console do Tracing Analysis.
spring:
application:
# This ends up as the service name in zipkin
name: sleuthDemo
zipkin:
# Uncomment to send to zipkin, replacing 192.168.99.100 with your zipkin IP address
baseUrl: <endpoint_short>
sleuth:
sampler:
probability: 1.0
sample:
zipkin:
# When enabled=false, traces log to the console. Comment to send to zipkin
enabled: true
Etapa 3: Verifique a configuração
Envie uma requisição HTTP para acionar o relatório de rastreamento:
http://localhost:3380/traced
Após enviar a requisição, verifique no console do Tracing Analysis se os dados de rastreamento estão chegando. Para conhecer outros caminhos de requisição disponíveis, consulte os métodos da classe com.alibaba.apm.SampleController no projeto de demonstração.
Instrumente com Spring 4.0 MVC ou Spring Boot
Configure o rastreamento via anotações Java para aplicações Spring 4.0 MVC ou Spring Boot.
Para ver um exemplo funcional, consulte o diretório springMvcDemo\webmvc4-boot|webmv4 no projeto de demonstração .
Etapa 1: Configure os beans de rastreamento e filtro
Adicione a seguinte classe de configuração. Substitua <endpoint> pelo endpoint obtido nos pré-requisitos.
/** Configuration for how to send spans to Zipkin */
@Bean Sender sender() {
return OkHttpSender.create("<endpoint>");
}
/** Configuration for how to buffer spans into messages for Zipkin */
@Bean AsyncReporter<Span> spanReporter() {
return AsyncReporter.create(sender());
}
/** Controls aspects of tracing such as the name that shows up in the UI */
@Bean Tracing tracing(@Value("${spring.application.name}") String serviceName) {
return Tracing.newBuilder()
.localServiceName(serviceName)
.propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "user-name"))
.currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
.addScopeDecorator(MDCScopeDecorator.create()) // puts trace IDs into logs
.build()
)
.spanReporter(spanReporter()).build();
}
/** decides how to name and tag spans. By default they are named the same as the http method. */
@Bean HttpTracing httpTracing(Tracing tracing) {
return HttpTracing.create(tracing);
}
/** Creates client spans for http requests */
// We are using a BPP as the Frontend supplies a RestTemplate bean prior to this configuration
@Bean BeanPostProcessor connectionFactoryDecorator(final BeanFactory beanFactory) {
return new BeanPostProcessor() {
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override public Object postProcessAfterInitialization(Object bean, String beanName) {
if (!(bean instanceof RestTemplate)) return bean;
RestTemplate restTemplate = (RestTemplate) bean;
List<ClientHttpRequestInterceptor> interceptors =
new ArrayList<>(restTemplate.getInterceptors());
interceptors.add(0, getTracingInterceptor());
restTemplate.setInterceptors(interceptors);
return bean;
}
// Lazy lookup so that the BPP doesn't end up needing to proxy anything.
ClientHttpRequestInterceptor getTracingInterceptor() {
return TracingClientHttpRequestInterceptor.create(beanFactory.getBean(HttpTracing.class));
}
};
}
/** Creates server spans for http requests */
@Bean Filter tracingFilter(HttpTracing httpTracing) {
return TracingFilter.create(httpTracing);
}
@Autowired SpanCustomizingAsyncHandlerInterceptor webMvcTracingCustomizer;
/** Decorates server spans with application-defined web tags */
@Override public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(webMvcTracingCustomizer);
}
Etapa 2: Ative a autoconfiguração
Adicione a seguinte linha ao arquivo src/main/resources/META-INF/spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
brave.webmvc.TracingConfiguration
Instrumente com Spring 2.5 ou 3.0 MVC
Configure o rastreamento por meio de definições de beans em XML para aplicações Spring 2.5 ou 3.0 MVC.
Para ver um exemplo funcional, consulte o diretório springMvcDemo\webmvc3|webmvc25 no projeto de demonstração .
Etapa 1: Configure o objeto de rastreamento
Adicione as seguintes definições de beans ao seu arquivo applicationContext.xml. Substitua <endpoint> pelo endpoint obtido nos pré-requisitos.
<bean class="zipkin2.reporter.beans.OkHttpSenderFactoryBean">
<property name="endpoint" value="<endpoint>"/>
</bean>
<!-- allows us to read the service name from spring config -->
<context:property-placeholder/>
<bean class="brave.spring.beans.TracingFactoryBean">
<property name="localServiceName" value="brave-webmvc3-example"/>
<property name="spanReporter">
<bean class="zipkin2.reporter.beans.AsyncReporterFactoryBean">
<property name="encoder" value="JSON_V2"/>
<property name="sender" ref="sender"/>
<!-- wait up to half a second for any in-flight spans on close -->
<property name="closeTimeout" value="500"/>
</bean>
</property>
<property name="propagationFactory">
<bean class="brave.propagation.ExtraFieldPropagation" factory-method="newFactory">
<constructor-arg index="0">
<util:constant static-field="brave.propagation.B3Propagation.FACTORY"/>
</constructor-arg>
<constructor-arg index="1">
<list>
<value>user-name</value>
</list>
</constructor-arg>
</bean>
</property>
<property name="currentTraceContext">
<bean class="brave.spring.beans.CurrentTraceContextFactoryBean">
<property name="scopeDecorators">
<bean class="brave.context.log4j12.MDCScopeDecorator" factory-method="create"/>
</property>
</bean>
</property>
</bean>
<bean class="brave.spring.beans.HttpTracingFactoryBean">
<property name="tracing" ref="tracing"/>
</bean>
Etapa 2: Adicione interceptadores
Registre o construtor do cliente HTTP de rastreamento e o interceptador de handler:
<bean class="brave.httpclient.TracingHttpClientBuilder"
factory-method="create">
<constructor-arg type="brave.http.HttpTracing" ref="httpTracing"/>
</bean>
<bean factory-bean="httpClientBuilder" factory-method="build"/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<bean class="brave.spring.webmvc.SpanCustomizingHandlerInterceptor"/>
</list>
</property>
</bean>
<!-- Loads the controller -->
<context:component-scan base-package="brave.webmvc"/>
Etapa 3: Adicione um filtro de servlet
Inclua o filtro de rastreamento no seu arquivo web.xml para interceptar todas as requisições recebidas:
<!-- Add the delegate to the standard tracing filter and map it to all paths -->
<filter>
<filter-name>tracingFilter</filter-name>
<filter-class>brave.spring.webmvc.DelegatingTracingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>tracingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Instrumente com Dubbo
A biblioteca de instrumentação Brave para Dubbo adiciona rastreamento distribuído a aplicações Dubbo RPC.
Para ver um exemplo funcional, consulte o diretório dubboDemo no projeto de demonstração .
Etapa 1: Adicione as dependências
Adicione as seguintes dependências ao seu arquivo pom.xml:
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-dubbo-rpc</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-spring-beans</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-context-slf4j</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-okhttp3</artifactId>
<version>2.7.9</version>
</dependency>
Etapa 2: Configure o objeto de rastreamento
Adicione as seguintes definições de beans à sua configuração XML do Spring. Substitua <endpoint> pelo endpoint obtido nos pré-requisitos.
<bean class="zipkin2.reporter.beans.OkHttpSenderFactoryBean">
<property name="endpoint" value="<endpoint>"/>
</bean>
<bean class="brave.spring.beans.TracingFactoryBean">
<property name="localServiceName" value="double-provider"/>
<property name="spanReporter">
<bean class="zipkin2.reporter.beans.AsyncReporterFactoryBean">
<property name="sender" ref="sender"/>
<!-- wait up to half a second for any in-flight spans on close -->
<property name="closeTimeout" value="500"/>
</bean>
</property>
<property name="currentTraceContext">
<bean class="brave.spring.beans.CurrentTraceContextFactoryBean">
<property name="scopeDecorators">
<bean class="brave.context.slf4j.MDCScopeDecorator" factory-method="create"/>
</property>
</bean>
</property>
</bean>
Etapa 3: Adicione filtros de rastreamento
Aplique o filtro de rastreamento nas configurações de provider e consumer:
// Server configuration
<dubbo:provider filter="tracing" />
// Client configuration
<dubbo:consumer filter="tracing" />
Instrumente manualmente uma aplicação Java
A instrumentação manual oferece controle granular sobre quais operações são rastreadas e quais metadados são anexados a cada span. Utilize este método quando a instrumentação automática não cobrir seu framework ou quando você precisar de uma granularidade personalizada para os spans.
Para ver um exemplo funcional, consulte o diretório manualDemo no projeto de demonstração .
Etapa 1: Adicione as dependências
Adicione as seguintes dependências ao seu arquivo pom.xml:
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-okhttp3</artifactId>
<version>2.7.9</version>
</dependency>
Etapa 2: Crie um tracer
Inicialize o tracer com seu endpoint do Zipkin. Substitua <endpoint> pelo endpoint obtido nos pré-requisitos.
private static final String zipkinEndPoint = "<endpoint>";
...
// Create a sender to transmit span data
OkHttpSender sender = OkHttpSender.newBuilder().endpoint(zipkinEndPoint).build();
// Create an asynchronous reporter
Reporter<Span> reporter = AsyncReporter.builder(sender).build();
tracing = Tracing.newBuilder().localServiceName(localServiceName).spanReporter(reporter).build();
Etapa 3: Crie spans
Crie um span raiz e aninhe spans filhos para representar suboperações:
private void firstBiz() {
// Create a root span
tracing.tracer().startScopedSpan("parentSpan");
Span span = tracing.tracer().currentSpan();
span.tag("key", "firstBiz");
secondBiz();
span.finish();
}
private void secondBiz() {
tracing.tracer().startScopedSpanWithParent("childSpan", tracing.tracer().currentSpan().context());
Span childSpan = tracing.tracer().currentSpan();
childSpan.tag("key", "secondBiz");
childSpan.finish();
System.out.println("end tracing,id:" + childSpan.context().traceIdString());
}
Etapa 4: Adicione tags personalizadas (opcional)
Anexe metadados aos spans para facilitar a solução de problemas. Por exemplo, registre um código de status HTTP:
tracer.activeSpan().setTag("http.status_code", "500");
Etapa 5: Propague o contexto de rastreamento entre serviços
Em sistemas distribuídos, o contexto de rastreamento (TraceId, ParentSpanId, SpanId, Sampled) deve acompanhar cada requisição RPC. Chame Inject no cliente para inserir o contexto nos cabeçalhos da requisição e chame Extract no servidor para lê-lo novamente.

Lado do cliente -- injetar contexto
// Start a new span representing a client request
oneWaySend = tracer.nextSpan().name(service + "/" + method).kind(CLIENT);
--snip--
// Add the trace context to the request, so it can be propagated in-band
tracing.propagation().injector(Request::addHeader)
.inject(oneWaySend.context(), request);
// Fire off the request asynchronously, totally dropping any response
request.execute();
// Start the client side and flush instead of finish
oneWaySend.start().flush();
Lado do servidor -- extrair contexto
// Pull the context out of the incoming request
extractor = tracing.propagation().extractor(Request::getHeader);
// Convert that context to a span which you can name and add tags to
oneWayReceive = nextSpan(tracer, extractor.extract(request))
.name("process-request")
.kind(SERVER)
... add tags etc.
// Start the server side and flush instead of finish
oneWayReceive.start().flush();
// You should not modify this span anymore as it is complete. However,
// you can create children to represent follow-up work.
next = tracer.newSpan(oneWayReceive.context()).name("step2").start();
Perguntas frequentes
P: Nenhum dado de rastreamento aparece após executar a demonstração.
R: Isso geralmente indica uma configuração incorreta do endpoint. Para diagnosticar o problema:
Verifique se o endpoint corresponde ao exibido na aba Access point information do console do Tracing Analysis.
Certifique-se de ter selecionado o tipo correto de cliente (Zipkin, não Jaeger) ao copiar o endpoint.
Se estiver usando um ponto de acesso VPC, confirme que sua aplicação está executando dentro da mesma VPC.
Para depurar mais a fundo, defina um breakpoint no método
parseResponseda classezipkin2.reporter.okhttp3.HttpCalle inspecione a resposta HTTP. Um erro403indica que a configuração do nome de usuário é inválida. Revise a configuração do seu endpoint.