Todos os produtos
Search
Central de documentação

Managed Service for OpenTelemetry:Report Java application data through Zipkin

Última atualização: Jul 05, 2026

O Zipkin é um sistema de rastreamento distribuído de código aberto, desenvolvido pelo Twitter para rastrear dados em tempo real. Ele agrega dados de monitoramento em tempo real coletados de vários sistemas heterogêneos. Use o Zipkin para relatar dados de aplicações Java ao Managed Service for OpenTelemetry.

O Zipkin oferece suporte a diversos frameworks Java por meio da biblioteca de instrumentação Brave, incluindo Apache HttpClient, Dubbo, gRPC, JAX-RS 2.X, Jersey Server, JMS, Kafka, MySQL, Netty, OkHttp, Servlet, Spark, Spring Boot e Spring MVC.

Escolha o método de instrumentação adequado ao seu framework:

Método

Mais indicado para

Esforço

Spring Cloud Sleuth

Aplicações Spring Boot

Menor — apenas configuração

Spring Boot ou Spring 4.0 MVC

Spring Boot ou Spring 4.x sem Sleuth

Baixo — beans de configuração Java

Spring 2.5 MVC ou Spring 3.0 MVC

Aplicações Spring MVC mais antigas

Baixo — definições de beans em XML

Dubbo

Aplicações Apache Dubbo RPC

Baixo — configuração XML + filtro

Instrumentação manual

Frameworks personalizados ou controle refinado

Médio — escrita de código de rastreamento

Zipkin data reporting flow

Pré-requisitos

Obtenha o endpoint do Zipkin no console do Tracing Analysis:

  1. Faça login no console do Tracing Analysis.

  2. No painel de navegação à esquerda, clique em Cluster Configurations. Em seguida, clique na aba Access point information.

  3. Na barra de navegação superior, selecione uma região. Na seção Cluster Information, ative Show Token.

  4. Na seção Client, clique em Zipkin.

  5. Copie o endpoint da coluna Related Information.

Endpoint information

Nota

Se a aplicação executar em um ambiente de produção da Alibaba Cloud, use um ponto de acesso VPC. Caso contrário, use um endpoint público. Utilize o endpoint v2, a menos que tenha um motivo específico para usar o v1.

Nas seções abaixo, substitua os seguintes espaços reservados pelos valores reais:

Espaço reservado

Descrição

<endpoint>

URL completa do endpoint Zipkin (termina com /api/v2/spans)

<endpoint_short>

URL base sem o caminho (apenas para Spring Cloud Sleuth)

Instrumentar com Spring Cloud Sleuth

O Spring Cloud Sleuth fornece auto-instrumentação para aplicações Spring Boot com configuração mínima. Esta é a abordagem recomendada para a maioria dos projetos Spring Boot.

Nota

Baixe o

projeto de demonstração

e acesse o diretório

sleuthDemo

para obter um exemplo executável.

Etapa 1: Adicionar dependências do Maven

<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 baseUrl como o endpoint obtido na aba Access point information da página Cluster Configurations. Obtenha o endpoint público, que termina com api/v2/spans, diretamente no console. Para o Spring Cloud Sleuth, utilize apenas a parte da URL base, sem o caminho /api/v2/spans.

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 integração

Envie uma solicitação de teste para acionar o rastreamento:

curl http://localhost:3380/traced

Para conhecer outros caminhos de solicitação, consulte os métodos em com.alibaba.apm.SampleController no projeto de demonstração.

Instrumentar com Spring Boot ou Spring 4.0 MVC

A autoconfiguração do Spring gerencia a maior parte da configuração de rastreamento. Utilize este método para aplicações Spring Boot ou Spring 4.x que não usam o Spring Cloud Sleuth.

Nota

Baixe o

projeto de demonstração

e acesse o diretório

springMvcDemo/webmvc4-boot

ou

springMvcDemo/webmv4

para obter um exemplo executável.

Etapa 1: Configure beans de rastreamento e filtro

/** 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: Registrar a autoconfiguração

Adicione a seguinte linha ao arquivo spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
brave.webmvc.TracingConfiguration

Instrumentar com Spring 2.5 MVC ou Spring 3.0 MVC

Para aplicações Spring MVC mais antigas, configure o rastreamento por meio de definições de beans em XML.

Nota

Baixe o

projeto de demonstração

e acesse o diretório

springMvcDemo/webmvc3

ou

springMvcDemo/webmvc25

para obter um exemplo executável.

Etapa 1: Configure o objeto de rastreamento no applicationContext.xml

<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: Adicionar um interceptor

<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: Adicionar um filtro de servlet

Adicione o filtro de rastreamento ao arquivo web.xml:

<!-- 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>

Instrumentar com Dubbo

Para aplicações Apache Dubbo, o Brave fornece um módulo de instrumentação dedicado.

Nota

Baixe o

projeto de demonstração

e acesse o diretório

dubboDemo

para obter um exemplo executável.

Etapa 1: Adicionar dependências do Maven

<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>
<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave</artifactId>
    <version>5.4.2</version>
</dependency>

Etapa 2: Configure o objeto de rastreamento

<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: Ative o filtro de rastreamento

Adicione o filtro de rastreamento às configurações do provedor e do consumidor:

<!-- Server-side configuration -->
<dubbo:provider filter="tracing" />
<!-- Client-side configuration -->
<dubbo:consumer filter="tracing" />

Instrumentar manualmente

Use a API do Brave diretamente quando nenhuma das integrações de framework acima atender ao seu caso de uso.

Nota

Baixe o

projeto de demonstração

e acesse o diretório

manualDemo

para obter um exemplo executável.

Etapa 1: Adicionar dependências do Maven

<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

private static final String zipkinEndPoint = "<endpoint>";
...
// Create a sender to transmit spans over HTTP
OkHttpSender sender = OkHttpSender.newBuilder().endpoint(zipkinEndPoint).build();

// Create an async reporter to batch and send spans
Reporter<Span> reporter = AsyncReporter.builder(sender).build();

tracing = Tracing.newBuilder().localServiceName(localServiceName).spanReporter(reporter).build();

Etapa 3: Crie spans

Crie um span raiz e spans filhos para representar unidades de trabalho:

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: Adicionar tags personalizadas (opcional)

As tags auxiliam na filtragem e na solução de problemas. Por exemplo, registre um código de status HTTP:

tracer.activeSpan().setTag("http.status_code", "500");

Etapa 5: Propagar o contexto de rastreamento entre serviços

Em um sistema distribuído, o contexto de rastreamento (TraceId, ParentSpanId, SpanId e Sampled) trafega entre os serviços por meio de cabeçalhos HTTP. Use Inject no lado do cliente para incorporar o contexto nas solicitações de saída e Extract no lado do servidor para lê-lo nas solicitações de entrada.

Trace context propagation flow

Injetar contexto no lado do cliente:

// 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();

Extrair contexto no lado do servidor:

// 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();

Verifique dados de rastreamento

Após concluir a instrumentação, execute a aplicação e envie algumas solicitações. Faça login no console do Tracing Analysis e verifique se os dados de rastreamento aparecem no painel da região correspondente.

Solução de problemas

Nenhum dado de rastreamento aparece após executar o programa de demonstração

Insira um breakpoint para depurar o método parseResponse em zipkin2.reporter.okhttp3.HttpCall e visualize o valor de retorno da solicitação de relato de dados. Se um erro 403 for retornado, a configuração do nome de usuário está inválida. Verifique a configuração do endpoint.