Spring Cloud Sleuth集成Zipkin以及一些Brave监控

Sleuth集成Zipkin

Spring Cloud中有 Spring Cloud Sleuth组件,Zipkin的客户端都是通过Sleuth集成在项目中,ZipkinServer启动在独立进程中。

什么是Zipkin

ZipkinTwitter 的一个开源项目,基于 Google Dapper实现。可以使用它来收集各个服务器上请求链路的跟踪数据,数据可以存储到外部服务当中,如ES等,并通过它提供的 REST API 接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。除了面向开发的API接口之外,它也提供了简单的 UI 组件帮助我们直观的搜索跟踪信息和分析请求链路明细。

还有一些比较优秀的链路跟踪系统,如SkyWalkingPinpointCAT等等,有空也可以看看,其实相比Zipkin,它们的侵入性相对更小,基于javaagent技术,不用在源码中显式调用。

启动Zipkin服务器

Zipkin可以微服务启动并通过注册中心注册,也可以用Docker启动,这里以微服务启动为例,编写一个Zipkin微服务

引入依赖:

<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-server</artifactId>
    <version>${zipkin-server.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-log4j2</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-autoconfigure-ui</artifactId>
    <version>${zipkin-server.version}</version>
</dependency>
<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
    <version>${zipkin-elasticsearch.version}</version>
</dependency>

配置application.yml

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

启动代码:

@EnableZipkinServer
@EnableDiscoveryClient
@SpringBootApplication
public class CloudServiceZipkinApplication {
    public static void main(String[] args) {
        SpringApplication.run(CloudServiceZipkinApplication.class, args);
    }
}

目前启动到:http://localhost:9411/,可以用浏览器查看

image-20220630191047978

配置客户端

Spring Cloud中有 Spring Cloud Sleuth组件,可以支持Zipkin,默认微服务之间的调用已经是支持的了,不过如果需要支持更多监控项目,可以到GitHubopenzipkin查找相关官方提供组件。

参考地址:https://zipkin.io/pages/tracers_instrumentation.html

Github地址:https://github.com/openzipkin/brave

import的方式添加父级pom,注意直接引入spring-cloud-starter-sleuth之后就可以了,不用再引入brave-bom等,重复引入依赖也没有问题,不过不能和已经存在的依赖版本不一致,否者可能因为版本问题报错,sleuth已经引入蛮多的brave包,如果需要更多brave,根据实际情况引入。

image-20220630195719708

在各个微服务中配置:

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

配置yml配置文件

# 使用注册中心方式
spring:
  zipkin:
    enabled: true
    discovery-client-enabled: true
# 使用URL方式(二选一)
spring:
  zipkin:
    enabled: true
    base-url: http://localhost:9411
# 如果想要提高采样率,能快速看到结果,采样率最大为1
spring:
  sleuth:
    sampler:
      probability: 1

调用后,可以看到微服务调用的链路信息,耗时,地址等信息都有:

image-20220630191621461

点开还有更详细信息:

image-20220630191746431

HttpClient的Brave集成

HttpClient组件是brave官方自带组件,默认sleuth已经引入,检查依赖如果没有,也可以尝试手动引入:

参考文档: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>

主要流程就是通过TracingHttpClientBuilder构建一个HttpClientBuilder,然后用HttpClientBuilder#build方法获取CloseableHttpClient,如果还需要其他定制化,可以在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);
}

使用的地方:

HttpClientBuilder httpClientBuilder = clientTraceProvider.getHttpClientBuilder("http-client");
CloseableHttpClient httpClient = httpClientBuilder.build();

实际示例效果:

image-20220701140352394

CXF的Brave集成

CXFbrave组件不是官方支持组件,是第三方开发组件,需要单独引入,以前老版本的CXF有个brave-cxf3组件,不过已经不用了,新版使用cxf-integration-tracing-brave,使用和CXF对应的版本就行。

参考文档: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>

加入配置,注意SenderCurrentTraceContext是从已有的sleuth环境中注入,不然TraceID会生成一个新的,整个调用过程就串联不起来,这里注入的其实就是ThreadLocalCurrentTraceContext

注意:客户端使用BraveClientFeature,服务端使用BraveFeature即可,比较方便集成。

@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);
}

然后在构建FactoryBean的地方添加对应的Feature就可以了。

@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
}

尝试调用后可以在zipkin中看到:

image-20220630185539770

CXF的brave集成完成。

常见错误

  1. 如果多个brave版本,可能引起下面的错误,建议排除一些依赖版本,保持统一的brave版本:

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

  1. 如果引入较新版本的brave,与内部版本不兼容,可能还有一下错误:

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

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇