关于java:Feign-服务调用使用-Zipkin-链路追踪

39次阅读

共计 6353 个字符,预计需要花费 16 分钟才能阅读完成。

0、介绍

散布式微服务时代,不便了业务的快速增长和服务的稳固,然而零碎呈现问题后,面对同业务多服务排查起来令人头大。这时候领导就想着集成分布式追踪零碎。Zipkin 是 Twitter 的一个开源我的项目,基于 Google Dapper 实现。能够应用它来收集各个服务器上申请链路的跟踪数据,并通过它提供的 REST API 接口来辅助咱们查问跟踪数据以实现对分布式系统的监控程序,从而及时地发现零碎中呈现的提早升高问题并找出零碎性能瓶颈的本源。除了面向开发的 API 接口之外,它也提供了不便的 UI 组件帮忙咱们直观的搜寻跟踪信息和剖析申请链路明细,比方:能够查问某段时间内各用户申请的解决工夫等。

1、环境筹备

Zipkin 服务依赖环境

Centos 7
Mysql 8

Zipkin 客户端我的项目版本

Springboot 2.2.5.RELEASE
Springcloudalibaba 2.2.1.RELEASE

2、Zipkin 服务装置

2.1、Docker 装置

# 拉取镜像
docker pull openzipkin/zipkin

#1、Web 连贯形式启动 
docker run --name zipkin-web -d -p 9411:9411 openzipkin/zipkin

#2、Rabbit 连贯形式启动 留神 RABBIT_ADDRESSES 的 Ip 要理论 Ip 
docker run -d --name zipkin-rabbitmq -p 9411:9411 -e RABBIT_ADDRESSES=192.168.1.105:5672 -e RABBIT_USER=guest -e RABBIT_PASSWORD=guest openzipkin/zipkin

#3、Rabbit 连贯形式启动,存储介质由内存改为 Mysql(临时有问题)docker run -d --name zipkin-rabbit-mysql -p 9411:9411 -e RABBIT_ADDRESSES=192.168.1.105:5672 -e RABBIT_USER=guest -e RABBIT_PASSWORD=guest -e STORAGE_TYPE=mysql -e MYSQL_HOST=192.168.1.105 -e MYSQL_TCP_PORT=13306 -e MYSQL_USER=root -e MYSQL_PASS=123456 -e MYSQL_DB=zipkin openzipkin/zipkin

2.2、Jar 装置

官网阐明 如果服务器装置了 JDK8 以及更高的,那么 Jar 包形式启动是最快的入门形式。

能够本地下载好 Jar 而后上传服务器再执行,也能够服务器间接下载再执行

  1. 下载最新 Jar 包,地址
  2. 服务器下载命令
curl -sSL https://zipkin.io/quickstart.sh | bash -s

Jar 服务启动

#1、Web 连贯形式启动  
java -jar zipkin.jar

#2、Rabbit 连贯形式启动 
java -jar zipkin-server-2.23.1-exec.jar --zipkin.collector.rabbitmq.addresses=localhost
#前面的 --zipkin.collector.rabbitmq.addresses=localhost 就是 RabbitMQ 的配置,这是默认的,如果要本人指定的用户名和明码能够参考上面的启动命令:nohup java -jar zipkin-server-2.23.1-exec.jar > zipkin.log --zipkin.collector.rabbitmq.addresses=localhost:5672 --zipkin.collector.rabbitmq.username=guest --zipkin.collector.rabbitmq.password=guest 2>&1 &

#3、Rabbit 连贯形式启动,批改存储介质,默认为内存,当初改为 Mysql,也能够应用 Elasticsearch 长久化
nohup java -jar zipkin-server-2.23.1-exec.jar > zipkin.log \
       --zipkin.collector.rabbitmq.addresses=localhost:5672 \
       --zipkin.collector.rabbitmq.username=guest \
       --zipkin.collector.rabbitmq.password=guest  \
       --zipkin.storage.type=mysql \
       --zipkin.storage.mysql.host=localhost \
       --zipkin.storage.mysql.port=3306 \
       --zipkin.storage.mysql.username=root \
       --zipkin.storage.mysql.password=root \
       --zipkin.storage.mysql.db=zipkin \
       2>&1 &

其余环境变量参数配置

属性 环境变量 形容
zipkin.collector.rabbitmq.concurrency RABBIT_CONCURRENCY 并发消费者数量,默认为 1
zipkin.collector.rabbitmq.connection-timeout RABBIT_CONNECTION_TIMEOUT 建设连贯时的超时工夫,默认为 60000 毫秒,即 1 分钟
zipkinzipkin.collector.rabbitmq.queue RABBIT_QUEUE 从中获取 span 信息的队列,默认为 zipkin
zipkin.collector.rabbitmq.uri RABBIT_URI 合乎 RabbitMQ URI 标准 的 URI,例如 amqp://user:pass@host:10000/vhost

如果设置了 URL,则以下属性将被疏忽

属性 环境变量 形容
zipkin.collector.rabbitmq.addresses RABBIT_ADDRESSES 用逗号分隔的 RabbitMQ 地址列表,例如 localhost:5672,localhost:5673
zipkin.collector.rabbitmq.password RABBIT_PASSWORD 连贯到 RabbitMQ 时应用的明码,默认为 guest
zipkinzipkinzipkin.collector.rabbitmq.username RABBIT_USER 连贯到 RabbitMQ 时应用的用户名,默认为 guest
zipkin.collector.rabbitmq.virtual-host RABBIT_VIRTUAL_HOST 应用的 RabbitMQ virtual host,默认为 /
zipkin.collector.rabbitmq.use-ssl RABBIT_USE_SSL 设置为 true 则用 SSL 的形式与 RabbitMQ 建设链接

摘抄自 地址

留神: 存储介质由默认的内存改为 Mysql,须要先建数据库 Zipkin,而后导入 zipkin 的默认库,建完库后执行如下内容即可

https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql-v1/src/main/resources/mysql.sql

3、我的项目集成 zipkin

我的项目集成应用 2 模块来阐明,模块名为 consumer 和 provider。次要以 Rabbit 连贯形式来介绍,也会正文说下 Web 的形式

3.1、模块工程别离引入 pom

<!-- 蕴含 Sleuth 和 Zipkin 依赖,看下图 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

<!-- 应用 Rabbit 连贯形式启动才须要上面依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

3.2、application.yml 增加配置

consumer

spring:
  zipkin:
#    base-url: http://192.168.1.105:9411 #Web 连贯形式应用
    service:
      name: consumer
    sender:
#      type: web #Web 连贯形式应用
      type: rabbit # 还有 activemq、kafka
  sleuth:
    sampler:
      probability: 1 #跟踪信息收集采样比例,默认 0.1,为 1 即 100%,收集所有 留神之前的版本是 percentage 新版本中更换为 probability
#      rate: 50 # 每秒速率,即每秒最多能跟踪的申请,rate 优先
    
  #Sleuth 应用 Rabbitmq 来向 Zipkin 发送数据
  rabbitmq:
    host: 192.168.1.105
    port: 5672
    username: guest
    password: guest

provider

spring:
  zipkin:
#    base-url: http://192.168.1.105:9411 #Web 连贯形式应用
    service:
      name: provider
    sender:
#      type: web #Web 连贯形式应用
      type: rabbit # 还有 activemq、kafka
  sleuth:
    sampler:
      probability: 1 #跟踪信息收集采样比例,默认 0.1,为 1 即 100%,收集所有 留神之前的版本是 percentage 新版本中更换为 probability
#      rate: 50 # 每秒速率,即每秒最多能跟踪的申请,rate 优先
    
  #Sleuth 应用 Rabbitmq 来向 Zipkin 发送数据
  rabbitmq:
    host: 192.168.1.105
    port: 5672
    username: guest
    password: guest

4、测试

4.1、启动服务

别离启动 consumer、provider,而后浏览器调用 consumer 的测试接口

http://localhost:8081/consumer1?name=1111

4.2、看日志

#consumer
2021-01-03 13:18:48.647  INFO [consumer,dd07a4eaac415456,dd07a4eaac415456,true] 6556 --- [nio-8081-exec-8] cn.songo.controller.ConsumerController   : consumer111>>>>>>:port:8081,age:25

#provider
2021-01-03 13:18:48.652  INFO [provider,dd07a4eaac415456,75c232c4616558ce,true] 596 --- [io-18080-exec-6] cn.songo.controller.ProviderController   : send---->age:261,port:18080

来看下下面的日志信息,==[consumer,dd07a4eaac415456,dd07a4eaac415456,true]==
,含意为 [我的项目名, TraceId( 雷同视为一申请), SpanId(每个服务节点惟一), 是否被 Zipkin 收录 ]

这里应用的是 Springboot 自带的日志框架 Logback,如果应用 Log4j2,则须要批改 Pattern 增加链路信息,参考如下内容。

%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%logger{50}:%L] [%X{X-B3-TraceId},%X{X-B3-ParentSpanId},%X{X-B3-SpanId},%X{X-Span-Export}] - %msg%n

4.3、Zipkin UI 查看

浏览器地址栏拜访

http://192.168.1.105:9411


能够看进去一个申请链路程序为 consumer->provider,还能够看到调用破费的工夫,到此就算配置胜利了。

5、与 Seata 集成的抵触问题

5.1、问题详情

spring-cloud-alibaba-seata 2.2.0.RELEASE
seata-spring-boot-starter 1.4.0

如果微服务中应用分布式事务 Seata,那集成 Zipkin 后,就会呈现问题服务调用服务失败的问题如下

com.netflix.client.ClientException: Load balancer does not have available server for client:ip

次要起因是 pom 引入的 Zipkin 蕴含 Sleuth,而 Sleuth 的配置类 TraceFeignClientAutoConfiguration 和 Seata 的配置类 SeataFeignClientAutoConfiguration 都创立了 Bean:feignHystrixBuilder,抵触导致下面的谬误。

5.2、问题解决

每个服务工程配置 Seata 拦截器类 SetSeataInterceptor,以拦截器的形式传递 XID

import com.bpmaxx.common.utils.StringUtils;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Component;

/**
 * @Description: 解决 seata 与 zipkin 整合时因 SeataFeignClientAutoConfiguration 和 TraceFeignClientAutoConfiguration 都创立 Bean:feignHystrixBuilder 抵触问题
 */
@Component
@ConditionalOnClass({RequestInterceptor.class,GlobalTransactional.class})
public class SetSeataInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate request) {String xid = RootContext.getXID();
        if (StringUtils.isNotEmpty(xid)) {request.header(RootContext.KEY_XID, xid);
        }
    }
}

启动类排除 SeataFeignClientAutoConfiguration.class

@SpringBootApplication(exclude = {SeataFeignClientAutoConfiguration.class})

记录如有不对烦请指出,后行感激

正文完
 0