Zipkin adalah sistem pelacakan terdistribusi open source yang dikembangkan oleh Twitter untuk melacak data waktu nyata. Sistem ini mengagregasi data Pemantauan waktu nyata yang dikumpulkan dari berbagai sistem heterogen. Panduan ini menjelaskan cara melakukan instrumentasi aplikasi Java Anda dengan pustaka Brave dan melaporkan data jejak ke ARMS Tracing Analysis melalui titik akhir yang kompatibel dengan Zipkin.
Pilih metode instrumentasi
Pilih metode yang sesuai dengan framework Anda. Spring Sleuth memerlukan konfigurasi paling sedikit dan direkomendasikan untuk proyek Spring Boot.
| Metode | Paling cocok untuk | Kompleksitas |
|---|---|---|
| Spring Sleuth | Layanan mikro Spring Cloud (direkomendasikan) | Rendah |
| Spring 4.0 MVC atau Spring Boot | Proyek modern berbasis anotasi Spring | Sedang |
| Spring 2.5 atau 3.0 MVC | Proyek lama berbasis XML Spring | Sedang |
| Dubbo | Aplikasi RPC Dubbo | Sedang |
| Instrumentasi manual | Kontrol penuh atas rentang dan tag | Tinggi |
Alur data
Aplikasi Anda menggunakan pustaka Brave untuk membuat rentang dan melaporkannya ke ARMS melalui titik akhir yang kompatibel dengan Zipkin.
Prasyarat
Dapatkan titik akhir Zipkin
Untuk melaporkan data jejak, Anda memerlukan titik akhir kompatibel Zipkin dari Konsol Analisis Tracing.
-
Masuk ke Konsol Analisis Tracing.
-
Di panel navigasi kiri, klik Cluster Configurations. Lalu, klik tab Access point information.
-
Di bilah navigasi atas, pilih Wilayah. Di bagian Cluster Information, aktifkan Show Token.
-
Di bagian Client, klik Zipkin.
Salin titik akhir dari kolom Related Information.
Jika aplikasi Anda berjalan di lingkungan produksi Alibaba Cloud, gunakan titik akses VPC Alibaba Cloud. Jika tidak, gunakan titik akhir publik.
Gunakan titik akhir v2 kecuali Anda memiliki alasan khusus untuk menggunakan v1.
Framework yang didukung
Brave menyediakan instrumentasi untuk framework Java berikut. Untuk daftar lengkapnya, lihat brave-instrumentation.
Apache HttpClient, Dubbo, gRPC, JAX-RS 2.X, Jersey Server, JMS, Kafka, MySQL, Netty, OkHttp, Servlet, Spark, Spring Boot, Spring MVC
Proyek demo
Demo yang berfungsi tersedia untuk setiap metode instrumentasi. Unduh proyek demo dan ikuti file README di direktori yang sesuai.
| Metode | Direktori demo |
|---|---|
| Instrumentasi manual | manualDemo |
| Spring 2.5 atau 3.0 MVC | springMvcDemo\webmvc3|webmvc25 |
| Spring 4.0 MVC atau Spring Boot | springMvcDemo\webmvc4-boot|webmv4 |
| Dubbo | dubboDemo |
| Spring Sleuth | sleuthDemo |
Instrumentasi dengan Spring Sleuth
Spring Cloud Sleuth menyediakan pelacakan terdistribusi otomatis untuk aplikasi Spring Boot dengan konfigurasi minimal. Integrasi ini secara native mendukung Zipkin untuk pelaporan jejak.
Langkah 1: Tambahkan dependensi
Tambahkan dependensi berikut ke pom.xml Anda:
<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>
Langkah 2: Konfigurasikan application.yml
Atur URL dasar Zipkin dan laju pengambilan sampel. Ganti <endpoint_short> dengan titik akhir publik yang diakhiri dengan api/v2/spans, yang diperoleh dari tab Access point information di Konsol Analisis Tracing.
spring:
application:
# Ini akan menjadi nama layanan di zipkin
name: sleuthDemo
zipkin:
# Hapus komentar untuk mengirim ke zipkin, ganti 192.168.99.100 dengan alamat IP zipkin Anda
baseUrl: <endpoint_short>
sleuth:
sampler:
probability: 1.0
sample:
zipkin:
# Saat enabled=false, jejak dicatat ke konsol. Beri komentar untuk mengirim ke zipkin
enabled: true
Langkah 3: Verifikasi pengaturan
Kirim permintaan HTTP untuk memicu pelaporan jejak:
http://localhost:3380/traced
Setelah mengirim permintaan, periksa Konsol Analisis Tracing untuk data jejak masuk. Untuk jalur permintaan tambahan, lihat metode di bawah com.alibaba.apm.SampleController dalam proyek demo.
Lakukan instrumentasi dengan Spring 4.0 MVC atau Spring Boot
Konfigurasikan pelacakan melalui anotasi Java untuk aplikasi Spring 4.0 MVC atau Spring Boot.
Untuk contoh yang berfungsi, lihat direktori springMvcDemo\webmvc4-boot|webmv4 dalam proyek demo.
Langkah 1: Konfigurasikan bean pelacakan dan filter
Tambahkan kelas konfigurasi berikut. Ganti <endpoint> dengan titik akhir yang Anda peroleh di bagian Prasyarat.
/** Konfigurasi cara mengirim rentang ke Zipkin */
@Bean Sender sender() {
return OkHttpSender.create("<endpoint>");
}
/** Konfigurasi cara mem-buffer rentang menjadi pesan untuk Zipkin */
@Bean AsyncReporter<Span> spanReporter() {
return AsyncReporter.create(sender());
}
/** Mengontrol aspek pelacakan seperti nama yang muncul di 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()) // memasukkan ID jejak ke log
.build()
)
.spanReporter(spanReporter()).build();
}
/** Menentukan cara memberi nama dan menandai rentang. Secara default, nama sama dengan metode HTTP. */
@Bean HttpTracing httpTracing(Tracing tracing) {
return HttpTracing.create(tracing);
}
/** Membuat rentang client untuk permintaan HTTP */
// Kami menggunakan BPP karena Frontend menyediakan bean RestTemplate sebelum konfigurasi ini
@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;
}
// Pencarian lazy agar BPP tidak perlu melakukan proxy apa pun.
ClientHttpRequestInterceptor getTracingInterceptor() {
return TracingClientHttpRequestInterceptor.create(beanFactory.getBean(HttpTracing.class));
}
};
}
/** Membuat rentang server untuk permintaan HTTP */
@Bean Filter tracingFilter(HttpTracing httpTracing) {
return TracingFilter.create(httpTracing);
}
@Autowired SpanCustomizingAsyncHandlerInterceptor webMvcTracingCustomizer;
/** Menambahkan tag web yang ditentukan aplikasi ke rentang server */
@Override public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(webMvcTracingCustomizer);
}
Langkah 2: Aktifkan auto-konfigurasi
Tambahkan baris berikut ke src/main/resources/META-INF/spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
brave.webmvc.TracingConfiguration
Instrumentasi dengan Spring 2.5 atau 3.0 MVC
Konfigurasikan pelacakan melalui definisi bean XML untuk aplikasi Spring 2.5 atau 3.0 MVC.
Untuk contoh yang berfungsi, lihat direktori springMvcDemo\webmvc3|webmvc25 dalam proyek demo.
Langkah 1: Konfigurasikan objek pelacakan
Tambahkan definisi bean berikut ke applicationContext.xml Anda. Ganti <endpoint> dengan titik akhir yang Anda peroleh di bagian Prasyarat.
<bean class="zipkin2.reporter.beans.OkHttpSenderFactoryBean">
<property name="endpoint" value="<endpoint>"/>
</bean>
<!-- memungkinkan kita membaca nama layanan dari konfigurasi spring -->
<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"/>
<!-- tunggu hingga setengah detik untuk rentang yang sedang dikirim saat menutup -->
<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>
Langkah 2: Tambahkan interceptor
Daftarkan builder klien HTTP pelacakan dan interceptor penanganan:
<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>
<!-- Memuat controller -->
<context:component-scan base-package="brave.webmvc"/>
Langkah 3: Tambahkan filter servlet
Tambahkan filter pelacakan ke web.xml Anda untuk mengintersepsi semua permintaan masuk:
<!-- Tambahkan delegasi ke filter pelacakan standar dan petakan ke semua jalur -->
<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>
Lakukan instrumentasi dengan Dubbo
Pustaka instrumentasi Brave Dubbo menambahkan pelacakan terdistribusi ke aplikasi RPC Dubbo.
Untuk contoh yang berfungsi, lihat direktori dubboDemo dalam proyek demo.
Langkah 1: Tambahkan dependensi
Tambahkan dependensi berikut ke pom.xml Anda:
<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>
Langkah 2: Konfigurasikan objek pelacakan
Tambahkan definisi bean berikut ke konfigurasi XML Spring Anda. Ganti <endpoint> dengan titik akhir yang Anda peroleh di bagian Prasyarat.
<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"/>
<!-- tunggu hingga setengah detik untuk rentang yang sedang dikirim saat menutup -->
<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>
Langkah 3: Tambahkan filter pelacakan
Terapkan filter pelacakan pada konfigurasi penyedia dan konsumen:
// Konfigurasi server
<dubbo:provider filter="tracing" />
// Konfigurasi klien
<dubbo:consumer filter="tracing" />
Lakukan instrumentasi manual pada aplikasi Java
Instrumentasi manual memberi Anda kontrol detail halus atas operasi mana yang dilacak dan metadata apa yang dilampirkan pada setiap rentang. Gunakan metode ini ketika instrumentasi otomatis tidak mencakup framework Anda atau ketika Anda memerlukan granularitas rentang kustom.
Untuk contoh yang berfungsi, lihat direktori manualDemo dalam proyek demo.
Langkah 1: Tambahkan dependensi
Tambahkan dependensi berikut ke pom.xml Anda:
<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>
Langkah 2: Buat tracer
Inisialisasi tracer dengan titik akhir Zipkin Anda. Ganti <endpoint> dengan titik akhir yang Anda peroleh di bagian Prasyarat.
private static final String zipkinEndPoint = "<endpoint>";
...
// Buat pengirim untuk mengirimkan data rentang
OkHttpSender sender = OkHttpSender.newBuilder().endpoint(zipkinEndPoint).build();
// Buat reporter asinkron
Reporter<Span> reporter = AsyncReporter.builder(sender).build();
tracing = Tracing.newBuilder().localServiceName(localServiceName).spanReporter(reporter).build();
Langkah 3: Buat rentang
Buat rentang akar dan bersarangkan rentang anak untuk merepresentasikan sub-operasi:
private void firstBiz() {
// Buat rentang akar
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());
}
Langkah 4: Tambahkan tag kustom (opsional)
Lampirkan metadata ke rentang untuk mempermudah troubleshooting. Misalnya, catat kode status HTTP:
tracer.activeSpan().setTag("http.status_code", "500");
Langkah 5: Sebarkan konteks jejak antar layanan
Dalam sistem terdistribusi, konteks jejak (TraceId, ParentSpanId, SpanId, Sampled) harus ikut serta dalam setiap permintaan RPC. Panggil Inject di sisi klien untuk menyematkan konteks ke header permintaan, dan panggil Extract di sisi server untuk membacanya kembali.
Sisi Klien – Menyuntikkan Konteks
// Mulai rentang baru yang merepresentasikan permintaan klien
oneWaySend = tracer.nextSpan().name(service + "/" + method).kind(CLIENT);
--snip--
// Tambahkan konteks jejak ke permintaan, sehingga dapat disebar secara in-band
tracing.propagation().injector(Request::addHeader)
.inject(oneWaySend.context(), request);
// Kirim permintaan secara asinkron, tanpa memperhatikan respons
request.execute();
// Mulai sisi klien dan flush alih-alih finish
oneWaySend.start().flush();
Sisi server -- extract konteks
// Ambil konteks dari permintaan masuk
extractor = tracing.propagation().extractor(Request::getHeader);
// Ubah konteks tersebut menjadi rentang yang dapat Anda beri nama dan tambahkan tag
oneWayReceive = nextSpan(tracer, extractor.extract(request))
.name("process-request")
.kind(SERVER)
... tambahkan tag dll.
// Mulai sisi server dan flush alih-alih finish
oneWayReceive.start().flush();
// Anda tidak boleh lagi memodifikasi rentang ini karena sudah selesai. Namun,
// Anda dapat membuat anak untuk merepresentasikan pekerjaan lanjutan.
next = tracer.newSpan(oneWayReceive.context()).name("step2").start();
FAQ
T: Data jejak tidak muncul setelah menjalankan demo.
J: Hal ini biasanya menunjukkan konfigurasi titik akhir yang salah. Untuk mendiagnosis masalah:
-
Verifikasi bahwa titik akhir sesuai dengan yang ditampilkan di tab Access point information di Konsol Analisis Tracing.
-
Pastikan Anda memilih jenis klien yang benar (Zipkin, bukan Jaeger) saat menyalin titik akhir.
-
Jika Anda menggunakan titik akses VPC, pastikan aplikasi Anda berjalan dalam VPC yang sama.
-
Untuk debugging lebih lanjut, atur breakpoint di metode
parseResponsedarizipkin2.reporter.okhttp3.HttpCalldan periksa respons HTTP. Error403menunjukkan konfigurasi username tidak valid. Periksa konfigurasi titik akhir Anda.