Zipkin, Twitter tarafından gerçek zamanlı verileri izlemek amacıyla geliştirilmiş açık kaynaklı dağıtık bir izleme sistemidir. Birden fazla farklı sistemden toplanan gerçek zamanlı izleme verilerini bir araya getirir. Bu kılavuzda, Java uygulamanızı Brave kitaplığı ile nasıl donatacağınızı ve iz verilerini Zipkin uyumlu bir uç nokta üzerinden ARMS Tracing Analysis hizmetine nasıl raporlayacağınızı öğreneceksiniz.
Donatım yöntemini seçin
Kullandığınız çerçeveyle eşleşen yöntemi seçin. Spring Sleuth en az yapılandırma gerektirir ve Spring Boot projeleri için önerilir.
| Yöntem | En uygun olduğu durum | Karmaşıklık |
|---|---|---|
| Spring Sleuth | Spring Cloud mikroservisleri (önerilen) | Düşük |
| Spring 4.0 MVC veya Spring Boot | Modern Spring anotasyon tabanlı projeler | Orta |
| Spring 2.5 veya 3.0 MVC | Eski Spring XML tabanlı projeler | Orta |
| Dubbo | Dubbo RPC uygulamaları | Orta |
| Manuel donatım | Span'ler ve etiketler üzerinde tam kontrol | Yüksek |
Veri akışı
Uygulamanız, span'leri oluşturmak ve bunları Zipkin uyumlu bir uç nokta üzerinden ARMS'e raporlamak için Brave kitaplığını kullanır.

Önkoşullar
Zipkin uç noktası alın
İz verilerini raporlamak için Tracing Analysis konsolundan Zipkin uyumlu bir uç noktaya ihtiyacınız vardır.
Tracing Analysis konsolu üzerinde oturum açın.
Sol gezinme bölmesinde Cluster Configurations seçeneğine tıklayın. Ardından Access point information sekmesine tıklayın.
Üst gezinme çubuğunda bir bölge seçin. Cluster Information bölümünde Show Token seçeneğini etkinleştirin.
Client bölümünde Zipkin seçeneğine tıklayın.
Related Information sütunundaki uç noktayı kopyalayın.

Uygulamanız Alibaba Cloud üretim ortamında çalışıyorsa bir Alibaba Cloud VPC erişim noktası kullanın. Aksi takdirde genel bir uç nokta kullanın.
Belirli bir nedeniniz yoksa v1 yerine v2 uç noktasını kullanın.
Desteklenen çerçeveler
Brave, aşağıdaki Java çerçeveleri için donatım desteği sağlar. Tam liste için brave-instrumentation adresine bakın.
Apache HttpClient, Dubbo, gRPC, JAX-RS 2.X, Jersey Server, JMS, Kafka, MySQL, Netty, OkHttp, Servlet, Spark, Spring Boot, Spring MVC
Demo projesi
Her donatım yöntemi için çalışan bir demo mevcuttur. demo projesini indirin ve ilgili dizindeki README dosyasındaki talimatları izleyin.
| Yöntem | Demo dizini |
|---|---|
| Manuel donatım | manualDemo |
| Spring 2.5 veya 3.0 MVC | springMvcDemo\webmvc3|webmvc25 |
| Spring 4.0 MVC veya Spring Boot | springMvcDemo\webmvc4-boot|webmv4 |
| Dubbo | dubboDemo |
| Spring Sleuth | sleuthDemo |
Spring Sleuth ile donatım
Spring Cloud Sleuth, minimum yapılandırma ile Spring Boot uygulamaları için otomatik dağıtık izleme sağlar. İz raporlaması için Zipkin ile yerel olarak entegre olur.
1. Adım: Bağımlılıkları ekleyin
Aşağıdaki bağımlılıkları pom.xml dosyanıza ekleyin:
<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>
2. Adım: application.yml dosyasını yapılandırın
Zipkin temel URL'sini ve örnekleme oranını ayarlayın. <endpoint_short> değerini, Tracing Analysis konsolundaki Access point information sekmesinden aldığınız ve api/v2/spans ile biten genel uç nokta ile değiştirin.
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
3. Adım: Kurulumu doğrulayın
İz raporlamasını tetiklemek için bir HTTP isteği gönderin:
http://localhost:3380/traced
İsteği gönderdikten sonra gelen iz verilerini görmek için Tracing Analysis konsolunu kontrol edin. Ek istek yolları için demo projesindeki com.alibaba.apm.SampleController altındaki yöntemlere bakın.
Spring 4.0 MVC veya Spring Boot ile donatım
Spring 4.0 MVC veya Spring Boot uygulamaları için Java anotasyonları aracılığıyla izlemeyi yapılandırın.
Çalışan bir örnek için demo projesindeki springMvcDemo\webmvc4-boot|webmv4 dizinine bakın.
1. Adım: İzleme ve filtre bean'lerini yapılandırın
Aşağıdaki yapılandırma sınıfını ekleyin. <endpoint> değerini Önkoşullar bölümünde aldığınız uç nokta ile değiştirin.
/** 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);
}
2. Adım: Otomatik yapılandırmayı etkinleştirin
src/main/resources/META-INF/spring.factories dosyasına aşağıdaki satırı ekleyin:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
brave.webmvc.TracingConfiguration
Spring 2.5 veya 3.0 MVC ile donatım
Spring 2.5 veya 3.0 MVC uygulamaları için XML bean tanımları aracılığıyla izlemeyi yapılandırın.
Çalışan bir örnek için demo projesindeki springMvcDemo\webmvc3|webmvc25 dizinine bakın.
1. Adım: İzleme nesnesini yapılandırın
Aşağıdaki bean tanımlarını applicationContext.xml dosyanıza ekleyin. <endpoint> değerini Önkoşullar bölümünde aldığınız uç nokta ile değiştirin.
<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>
2. Adım: İnterceptor'ları ekleyin
İzleme HTTP istemci oluşturucusunu ve işleyici interceptor'ını kaydedin:
<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"/>
3. Adım: Servlet filtresi ekleyin
Gelen tüm istekleri yakalamak için web.xml dosyanıza izleme filtresini ekleyin:
<!-- 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>
Dubbo ile donatım
Brave Dubbo izleme kitaplığı, Dubbo RPC uygulamalarına dağıtık izleme özelliği ekler.
Çalışan bir örnek için demo projesindeki dubboDemo dizinine bakın.
1. Adım: Bağımlılıkları ekleyin
Aşağıdaki bağımlılıkları pom.xml dosyanıza ekleyin:
<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>
2. Adım: İzleme nesnesini yapılandırın
Aşağıdaki bean tanımlarını Spring XML yapılandırmanıza ekleyin. <endpoint> değerini Önkoşullar bölümünde aldığınız uç nokta ile değiştirin.
<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>
3. Adım: İzleme filtrelerini ekleyin
İzleme filtresini hem sağlayıcı hem de tüketici yapılandırmalarına uygulayın:
// Server configuration
<dubbo:provider filter="tracing" />
// Client configuration
<dubbo:consumer filter="tracing" />
Java uygulamasını manuel olarak donatma
Manuel donatım, hangi işlemlerin izleneceği ve her span'e hangi meta verilerin ekleneceği üzerinde hassas kontrol sağlar. Otomatik donatımın çerçevenizi kapsamadığı durumlarda veya özel span granülerliğine ihtiyaç duyduğunuzda bu yöntemi kullanın.
Çalışan bir örnek için demo projesindeki manualDemo dizinine bakın.
1. Adım: Bağımlılıkları ekleyin
Aşağıdaki bağımlılıkları pom.xml dosyanıza ekleyin:
<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>
2. Adım: Bir tracer oluşturun
Tracer'ı Zipkin uç noktanızla başlatın. <endpoint> değerini Önkoşullar bölümünde aldığınız uç nokta ile değiştirin.
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();
3. Adım: Span'ler oluşturun
Alt işlemleri temsil etmek için bir kök span oluşturun ve çocuk span'leri iç içe yerleştirin:
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());
}
4. Adım: Özel etiketler ekleyin (isteğe bağlı)
Sorun gidermeyi kolaylaştırmak için span'lere meta veri ekleyin. Örneğin, bir HTTP durum kodunu kaydedin:
tracer.activeSpan().setTag("http.status_code", "500");
5. Adım: İz bağlamını hizmetler arasında yaygınlaştırın
Dağıtık sistemlerde iz bağlamının (TraceId, ParentSpanId, SpanId, Sampled) her RPC isteğiyle birlikte taşınması gerekir. Bağlamı istek üstbilgilerine gömmek için istemcide Inject çağrısı yapın ve sunucuda bunu geri okumak için Extract çağrısı yapın.

İstemci tarafı -- bağlamı ekleme
// 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();
Sunucu tarafı -- bağlamı çıkarma
// 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();
SSS
S: Demoyu çalıştırdıktan sonra iz verisi görünmüyor.
C: Bu durum genellikle hatalı bir uç nokta yapılandırmasından kaynaklanır. Sorunu teşhis etmek için:
Uç noktanın Tracing Analysis konsolunun Access point information sekmesinde gösterilenle eşleştiğini doğrulayın.
Uç noktayı kopyalarken doğru istemci türünü (Jaeger değil, Zipkin) seçtiğinizden emin olun.
Bir VPC erişim noktası kullanıyorsanız uygulamanızın aynı VPC içinde çalıştığını onaylayın.
Daha fazla hata ayıklama yapmak için
zipkin2.reporter.okhttp3.HttpCalliçindekiparseResponseyöntemine bir kesme noktası koyun ve HTTP yanıtını inceleyin.403hatası, kullanıcı adı yapılandırmasının geçersiz olduğunu gösterir. Uç nokta yapılandırmanızı kontrol edin.