rabbitmq+sleuth+zinkip 分布式链路追踪

我们都知道,微服务之间通过feign传递,在复杂的微服务架构系统中,几乎每一个前端请求都会形成一个复杂的分布式服务调用链路,在每条链路中任何一个依赖服务出现延迟超时或者错误都有可能引起整个请求最后的失败。当业务流程足够复杂时,一个完整的HTTP请求调用链一般会经过多个微服务系统,要通过日志来跟踪一整个调用链变得不再那么简单。通过sleuth可以很方便的看出每个采集请求的耗时情况,分析出哪些服务调用比较耗时,当服务调用的耗时随着请求量的增大而增大时,可以针对业务做一些优化措施。所以我们可以通过我们可以通过Spring Cloud Sleuth来解决这个问题。这里我们将演示如何通过Spring Cloud Sleuth来追踪这个过程,并借助Zipkin以图形化界面的方式展示。 展示之前,分别介绍一下rabbitmq、sleuth、zinkip。

  1. rabbitmq

    • RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而群集和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。
  2. sleuth和zinkip

    • sleuth 是spring cloud的组成部分之一,为springcloud应用实现了一种分布式追踪解决方案,其兼容了zinkip,HTrace和log-based追踪
    • Zipkin 是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper 的论文设计而来,由 Twitter公司开发贡献。其主要功能是聚集来自各个异构系统的实时监控数据,用来追踪微服务架构下的系统延时问题。Zipkin 的用户界面可以呈现一幅关联图表,以显示有多少被追踪的请求通过了每一层应用。Zipkin 以 Trace 结构表示对一次请求的追踪,又把每个 Trace 拆分为若干个有依赖关系的 Span。在微服务架构中,一次用户请求可能会由后台若干个服务负责处理,那么每个处理请求的服务就可以理解为一个 Span(可以包括 API 服务,缓存服务,数据库服务以及报表服务等)。当然这个服务也可能继续请求其他的服务,因此 Span 是一个树形结构,以体现服务之间的调用关系。Zipkin 的用户界面除了可以查看 Span 的依赖关系之外,还以瀑布图的形式显示了每个 Span 的耗时情况,可以一目了然的看到各个服务的性能状况。

sleuth中的一些术语

  1. Span:基本工作单元,例如,在一个新建的span中发送一个RPC等同于发送一个回应请求给RPC,span通过一个64位ID唯一标识,trace以另一个64位ID表示,span还有其他数据信息,比如摘要、时间戳事件、关键值注释(tags)、span的ID、以及进度ID(通常是IP地址) ,span在不断的启动和停止,同时记录了时间信息,当你创建了一个span,你必须在未来的某个时刻停止它。
  2. Trace:一系列spans组成的一个树状结构,例如,如果你正在跑一个分布式工程,你可能需要创建一个trace。
  3. Annotation:用来及时记录一个事件的存在,一些核心annotations用来定义一个请求的开始和结束
  • cs - Client Sent -客户端发起一个请求,这个annotion描述了这个span的开始
  • sr - Server Received -服务端获得请求并准备开始处理它,如果将其sr减去cs时间戳便可得到网络延迟
  • ss - Server Sent -注解表明请求处理的完成(当请求返回客户端),如果ss减去sr时间戳便可得到服务端需要的处理请求时间
  • cr - Client Received -表明span的结束,客户端成功接收到服务端的回复,如果cr减去cs时间戳便可得到客户端从服务端获取回复的所有所需时间

接下来就开始搭建
这里cloud版本用的Greenwich.SR1,boot使用的是2.1.6

1.在pom.xml中 引入sleuth依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency> 

2.模拟两个日志 这两个服务之间通过feign调用,由test调用system,这里本来有一个注册中心,这里就不在演示了

test模块

@Slf4j
@RestController
public class TestController {

    @Autowired
    private IHelloService helloService;

    @GetMapping("hello")
    public String hello(String name) {
    log.info("Feign调用system的/hello服务");
    return this.helloService.hello(name);
   }
}    

在test模块的service包下创建IHelloService

@FeignClient(value = "system",contextId = "helloServiceClient")
public interface IHelloService {
    @GetMapping("hello")
    String hello(@RequestParam("name") String name);
}

system 模块

@Slf4j
@RestController
public class TestController {

    @GetMapping("hello")
    public String hello(String name) {
        log.info("/hello服务被调用");
        return "hello" + name;
    }
}

3.访问接口 localhost:8202/test/hello?name=sleuth:会出现两个我们自定义的日志

启动的时候查看test模块产生的

2019-08-23 14:22:51.774  INFO [test,72bb0469bee07104,72bb0469bee07104,false] 22728 --- [nio-8202-exec-1] c.m.f.s.test.controller.TestController   : Feign调用system的/hello服务

启动的时候查看system模块产生的

2019-08-23 14:22:52.469  INFO [system,72bb0469bee07104,43597a6edded6f2e,false] 812 --- [nio-8201-exec-2] c.m.f.s.s.controller.TestController      : /hello服务被调用

可以看到,日志里出现了[Test,72bb0469bee07104,72bb0469bee07104,false]信息,这些信息由Spring Cloud Sleuth生成,用于跟踪微服务请求链路。这些信息包含了4个部分的值,它们的含义如下:

  1. system微服务的名称,与spring.application.name对应;
  2. 72bb0469bee07104称为Trace ID,在一条完整的请求链路中,这个值是固定的。观察上面的日志即可证实这一点;
  3. 43597a6edded6f2e称为Span ID,它表示一个基本的工作单元;
  4. false表示是否要将该信息输出到Zipkin等服务中来收集和展示,这里我们还没有集成Zipkin,所以为false。

下面我们来整合Zipkin

在整合Zipkin之前,我们需要先搭建RabbitMQ。RabbitMQ用于收集Sleuth提供的追踪信息,然后Zipkin Server从RabbitMQ里获取,这样可以提升性能。

在安装RabbitMQ之前,需要先安装Erlang/OTP,下载地址为:http://www.erlang.org/downloads/,下载exe文件安装即可。
安装完毕后,下载RabbitMQ,下载地址为 :
http://www.rabbitmq.com/install-windows.html,下载exe文件安装即可。

安装完RabbitMQ之后,我们到RabbitMQ安装目录的sbin下执行如下命令

rabbitmq-plugins enable rabbitmq_management

然后在浏览器中输入http://localhost:15672,默认用户名和密码都是guest,登录后可看到:

image

点击Admin Tab页面,新增一个用户:

image

用户名为febs,密码为123456,角色为管理员。新添加的用户还是No access状态,需要进一步对该用户进行授权后,方可以远程通过该用户名访问。点击该新增用户名。进入授权页面,点击Set permission按钮,进行用户授权操作。
安装好RabbitMQ后,我们开始整合Zipkin。在较低版本的Spring Cloud中,我们可以自己搭建Zipkin Server,现在我们只能使用官方搭建好的Zipkin Server,地址为:https://github.com/openzipkin/zipkin

在cmd窗口下运行下面这条命令(windows下没有curl环境的话,可以在git bash中运行这条命令),下载zipkin.jar:

curl -sSL https://zipkin.io/quickstart.sh | bash -s

如果下载速度极慢,可以复制链接到迅雷下载中下载,下载后重命名为zipkin.jar即可。

zipkin支持将追踪信息保存到MySQL数据库,所以在运行zipkin.jar之前,我们先准备好相关库表,SQL脚本地址为:

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

库表准备好后,运行下面这条命令启动zipkin.jar:

java -jar zipkin.jar --server.port=8402 --zipkin.storage.type=mysql --zipkin.storage.mysql.db=febs_cloud_base --zipkin.storage.mysql.username=root --zipkin.storage.mysql.password=123456 --zipkin.storage.mysql.host=localhost --zipkin.storage.mysql.port=3306 --zipkin.collector.rabbitmq.addresses=localhost:5672 --zipkin.collector.rabbitmq.username=febs --zipkin.collector.rabbitmq.password=123456

上面命令指定了数据库链接和RabbitMQ链接信息。更多可选配置可以解压zipkin.jar,查看zipkin\BOOT-INF\classes路径下的zipkin-server-shared.yml配置类源码。

启动好zipkin.jar后,在对应模块的pom里引入如下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit</artifactId>
</dependency>

修改对应模块的application.yml

spring:
  zipkin:
    sender:
      type: rabbit
  sleuth:
    sampler:
      probability: 1
  rabbitmq:
    host: localhost
    port: 5672
    username: febs
    password: 123456

spring.zipkin.sender.type指定了使用RabbitMQ收集追踪信息;

spring.sleuth.sampler.probability默认值为0.1,即采样率才1/10,发送10笔请求只有一笔会被采集。为了测试方便,我们可以将它设置为1,即100%采样;

spring.rabbitmq用于配置RabbitMQ连接信息,你可能会问,为什么刚刚RabbitMQ端口是15672,这里却配置为5672,是不是写错了呢?其实不是,15672是RabbitMQ的管理页面端口,5672是AMPQ端口。

添加好配置后,启动system和test模块,发送一笔localhost:8202/test/hello?name=夏天请求后,使用浏览器访问http://localhost:8402/zipkin/链接,然后点击图中所示

image
image
image

查看依赖关系:

image

查看数据表,看是否存储了信息:

image

最后,最近很多小伙伴找我要Linux学习路线图,于是我根据自己的经验,利用业余时间熬夜肝了一个月,整理了一份电子书。无论你是面试还是自我提升,相信都会对你有帮助!目录如下:

免费送给大家,只求大家金指给我点个赞!

电子书 | Linux开发学习路线图

也希望有小伙伴能加入我,把这份电子书做得更完美!

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

推荐阅读:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,271评论 6 524
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,533评论 3 405
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,580评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,203评论 1 303
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,204评论 6 401
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,664评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,014评论 3 431
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,991评论 0 280
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,536评论 1 326
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,558评论 3 347
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,678评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,267评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,997评论 3 341
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,429评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,580评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,259评论 3 382
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,744评论 2 366