Original link: https://fugary.com/?p=357
Sleuth integrates with Zipkin
There are Spring Cloud
Cloud Sleuth components in Spring Cloud, Zipkin
clients are integrated into the project through Sleuth
, and ZipkinServer
started in a separate process.
What is Zipkin
Zipkin
is an open source project of Twitter
, based on Google Dapper
. It can be used to collect the trace data of the request link on each server, the data can be stored in external services, such as ES
, etc., and through the REST API
interface it provides to assist us in querying the trace data to realize the monitoring program of the distributed system , so as to find out the problem of rising latency in the system in time and find out the root cause of system performance bottleneck. In addition to the development-oriented API
interface, it also provides simple UI
components to help us intuitively search for tracking information and analyze request link details.
There are also some excellent link tracking systems, such as SkyWalking , Pinpoint , CAT , etc. You can take a look when you have time. In fact, they are relatively less intrusive than Zipkin
. They are based on javaagent
technology and do not need to be explicitly in the source code. transfer.
Start the Zipkin server
Zipkin
can be started by microservices and registered through the registry, or it can be started by Docker
. Here we take microservice startup as an example to write a Zipkin
spring.application.name: cloud-service-zipkin server: port: 9411 # 注册中心配置(根据实际情况配置) spring: cloud: consul: host: xxxx port: 8500 # Elasticsearch配置,存储Zipkin数据zipkin: storage: type: elasticsearch elasticsearch: hosts: xxx.xxx.xxx.xxx:9200
Startup code:
@EnableZipkinServer @EnableDiscoveryClient @SpringBootApplication public class CloudServiceZipkinApplication { public static void main(String[] args) { SpringApplication.run(CloudServiceZipkinApplication.class, args); } }
Currently launched to: http://localhost:9411/, you can view it with a browser .
Configure the client
There are Spring Cloud
Cloud Sleuth components in Spring Cloud, which can support Zipkin
. By default, calls between microservices are already supported. However, if you need to support more monitoring projects, you can go to openzipkin
on GitHub
to find relevant officially provided components.
Reference address: https://zipkin.io/pages/tracers_instrumentation.html
Github address: https://github.com/openzipkin/brave
Add the parent pom
in the way of import
. Note that you can directly import spring-cloud-starter-sleuth . You don’t need to introduce brave-bom. The user may report an error due to version problems. sleuth has introduced quite a few brave packages. If you need more brave, introduce them according to the actual situation.
Configure in each microservice:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <!--sleuth已经包含下面的brave配置了,不用再引入,只记录下,如果有些工具类没有使用sleuth编译环境可能有用--> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-bom</artifactId> <version>${brave.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave</artifactId> </dependency>
Configure yml configuration file
# 使用注册中心方式spring: zipkin: enabled: true discovery-client-enabled: true # 使用URL方式(二选一) spring: zipkin: enabled: true base-url: http://localhost:9411
After the call, you can see the link information, time-consuming, address and other information of the microservice call:
Click on for more details:
Brave integration for HttpClient
The HttpClient component is the official built-in component of Brave. By default, sleuth has been introduced. If there is no check dependency, you can also try to import it manually:
Reference documentation: https://github.com/openzipkin/brave/tree/master/instrumentation/httpclient
<dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-instrumentation-httpclient</artifactId> <version>${brave.version}</version> </dependency>
The main process is to build an HttpClientBuilder
through TracingHttpClientBuilder
, and then use the HttpClientBuilder#build
method to obtain the CloseableHttpClient
. If you need other customizations, you can add more configuration information to the HttpClientBuilder
:
@Autowired(required = false) protected Sender sender; @Autowired(required = false) protected CurrentTraceContext currentTraceContext; @Override public HttpClientBuilder getHttpClientBuilder(String name) { Tracing brave = Tracing .newBuilder() .localServiceName(name) // 名字.spanReporter(AsyncReporter.builder(sender).build()) // 发送上报.sampler(Sampler.ALWAYS_SAMPLE) // 采样配置.currentTraceContext(currentTraceContext) // 本地TraceContext,ThreadLocal .build(); // 如果需要更多信息,可以使用HttpClientParser来定制HttpTracing httpTracing = HttpTracing.newBuilder(brave) .clientParser(new HttpClientSpanParser()).build(); return TracingHttpClientBuilder.create(httpTracing); }
Where to use:
HttpClientBuilder httpClientBuilder = clientTraceProvider.getHttpClientBuilder("http-client"); CloseableHttpClient httpClient = httpClientBuilder.build();
Actual example effect:
Brave integration for CXF
The brave
component of CXF
is not an official support component, it is a third-party development component and needs to be introduced separately. The old version of CXF
had a brave-cxf3
component, but it is no longer used. The new version uses cxf-integration-tracing-brave
, which corresponds to CXF
version will do.
Reference documentation: https://cxf.apache.org/docs/using-openzipkin-brave.html
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-integration-tracing-brave</artifactId> <version>${cxf.version}</version> <!--如果自带的brave依赖版本和已经存在版本不一致,可以考虑排除相关依赖,否者可能会启动报错--> <exclusions> <exclusion> <groupId>io.zipkin.brave</groupId> <artifactId>brave</artifactId> </exclusion> <exclusion> <groupId>io.zipkin.brave</groupId> <artifactId>brave-instrumentation-http</artifactId> </exclusion> </exclusions> </dependency>
Add the configuration. Note that Sender
and CurrentTraceContext
are injected from the existing sleuth
environment. Otherwise, a new TraceID
will be generated, and the entire calling process will not be connected in series. What is injected here is actually ThreadLocalCurrentTraceContext
.
Note: The client uses BraveClientFeature
, and the server uses BraveFeature
, which is more convenient for integration.
@Autowired(required = false) protected Sender sender; @Autowired(required = false) protected CurrentTraceContext currentTraceContext; // Sender和CurrentTraceContext为自动注入, name需要自定义protected Feature getBraveFeature(String name) { Tracing brave = Tracing .newBuilder() .localServiceName(name) .spanReporter(AsyncReporter.builder(sender).build()) .sampler(Sampler.ALWAYS_SAMPLE) .currentTraceContext(currentTraceContext) .build(); return new BraveClientFeature(brave); }
Then add the corresponding Feature
in the place where FactoryBean
is built.
@Bean public SomeWebService someWebService() { JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean(); bean.setAddress(address); bean.setServiceClass(SomeWebService.class); bean.getFeatures().add(getBraveFeature(SomeWebService.class.getSimpleName())); // 这里引入brave的feature SomeWebService client = bean.create(SomeWebService.class); return client; // 直接返回client }
You can see in zipkin after trying to call:
Brave integration of CXF is complete.
Common mistakes
- If there are multiple Brave versions, the following errors may be caused. It is recommended to exclude some dependent versions and maintain a unified Brave version:
Caused by: java.lang.ClassNotFoundException: brave.TracingCustomizer
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
… 110 common frames omitted
- If a newer version of Brave is introduced that is not compatible with the internal version, there may be the following errors:
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration.sleuthCurrentTraceContextBuilder(TraceAutoConfiguration.java:193)
The following method did not exist:
brave.propagation.ThreadLocalCurrentTraceContext.newBuilder()Lbrave/propagation/CurrentTraceContext$Builder;
The method’s class, brave.propagation.ThreadLocalCurrentTraceContext, is available from the following locations:
jar:file:/C:/Users/gary.fu/.m2/repository/io/zipkin/brave/brave/5.13.10/brave-5.13.10.jar!/brave/propagation/ThreadLocalCurrentTraceContext.class
It was loaded from the following location:
file:/C:/Users/gary.fu/.m2/repository/io/zipkin/brave/brave/5.13.10/brave-5.13.10.jar
This article is reprinted from: https://fugary.com/?p=357
This site is for inclusion only, and the copyright belongs to the original author.