「Java分享客栈」随时用随时翻:微服务链路追踪之zipkin搭建
前言
微服务治理方案中,链路追踪是必修课,SpringCloud的组件其实使用很简单,生产环境中真正令人头疼的往往是软件维护,接口在微服务间的调用究竟哪个环节出现了问题,哪个环节耗时较长,这都是项目上线后一定会遇到的问题,为了解决这些问题链路追踪便应运而生了。
主流方案
1)、SkyWalking:这应该是目前最主流的方案了,我所在公司今年的新项目就开始使用这个,效果确实很显著,功能强大,最重要还是国产的,后面不用看了我们支持国产吧!开个玩笑哈哈,其实这个框架也有缺点,就是稍微有点重,比较适合稍大一点的项目,但可预见后面几年都是最受欢迎的方案;
2)、Zipkin:这个是老牌链路追踪方案,已经被非常多项目验证过实用性,相比较于SkyWalking,我个人更喜欢这个框架,因为更轻量级,安装也非常简单,是中小规模的微服务项目首选方案。
用法
1、zipkin环境搭建
官方提供了docker版本,十分简单。也可以下载编译好的zipkin.jar来运行,是springboot项目。
1)、启动
默认端口号启动zipkin服务,默认端口9411.
java -jar zipkin.jar
2)、指定端口号
java -jar zipkin.jar --server.port=8080
3)、指定访问RabbitMQ
java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=127.0.0.1
4)、启动效果
2、SpringCloud整合zipkin
springcloud其它基础依赖包引入这里省略,直接模拟场景。
会员服务:zipkin_member
订单服务:zipkin_order
消息服务:zipkin_msg
过程:会员服务调用订单服务,订单服务调用消息服务。
1)、引入依赖
<!-- zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
2)、application.yml配置
注意事项:
a)、加上服务名,RestTemplate调用时会用到;
b)、加上zipkin服务端地址;
c)、加上probability采集率设置,默认0.1,测试环境改为1.0保证每次都采集,生产环境适当抽样即可。(因为10000个请求抽样1000个也能发现问题了,没必要全部都采集)
3)、引入RestTemplate
这里restTemplate主要用来进行接口调用查看链路追踪是否生效
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
4)、controller调用
会员调用订单
订单调用消息
消息处理具体业务
5)、查看效果
启动Zipkin服务端,访问:http://127.0.0.1:9411
执行controller接口
查看链路追踪,可以看到,接口调用的链路已经在zipkin显现了。
3、zipkin整合RabbitMQ异步采集
springboot2.0之后,官方不再推荐使用自建的zipkin server,而是直接使用编译好的zipkin.jar来给我们使用。
zipkin.jar中的yml配置可以参考:https://github.com/openzipkin/zipkin/blob/master/zipkin-server/src/main/resources/zipkin-server-shared.yml
1)、指定RabbitMQ为服务器
启动zipkin服务时指定rabbitmq为服务器即可,得先启动rabbitmq服务器。
java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=192.168.239.132
启动之后,可以发现rabbitmq中会自动新增一个zipkin队列,表示绑定成功。
2)、引入中间依赖
给每个微服务引入stream和rabbitmq的中间件依赖
<!-- 引入和rabbitmq的中间依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
3)、yml配置
修改每个微服务的application.yml,加上rabbitmq的配置。
rabbitmq:
host: 192.168.239.132
port: 5672
username: guest
password: guest
4)、启动和调用
启动微服务,执行调用。
5)、MQ是否收到消息
看rabbitmq是否有收消息,队列有反应说明rabbitmq收到消息了。
6)、Zipkin是否采集信息
看zipkin是否采集了链路信息
7)、验证积压消息
关掉zipkin服务,看消息是否会积压在rabbitmq,再启动zipkin服务,看消息是否会被消费并且获取到链路信息。
获取消息查看,发现获取到的就是traceId相关的json数据,证明整个过程都是正常的。
重新再启动zipkin服务,发现rabbitmq积压的消息就被消费了。
并且也能获取到链路信息
4、zipkin使用MySQL存储
zipkin.jar中的yml配置可以参考,里面有关于mysql的配置或者其他如elasticsearch的配置:
这节我们在上一节MQ的基础上增加MySQL的启动配置项
1)、指定MySQL
命令看着很长,其实仔细看发现很简单,都是见名知义,不必死记硬背。
java -jar zipkin.jar
--zipkin.collector.rabbitmq.addresses=192.168.239.132
--zipkin.storage.type=mysql
--zipkin.storage.mysql.host=127.0.0.1
--zipkin.storage.mysql.port=3306
--zipkin.storage.mysql.username=root
--zipkin.storage.mysql.password=123456
--zipkin.storage.mysql.db=zipkin
2)、创建zipkin数据库
根据1中命令配置的信息,创建zipkin数据库,并执行语句创建zipkin采集记录的三张表。
这里我也贴出来 zipkin-mysql.sql
CREATE TABLE IF NOT EXISTS zipkin_spans (
`trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id` BIGINT NOT NULL,
`id` BIGINT NOT NULL,
`name` VARCHAR(255) NOT NULL,
`remote_service_name` VARCHAR(255),
`parent_id` BIGINT,
`debug` BIT(1),
`start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
`duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query',
PRIMARY KEY (`trace_id_high`, `trace_id`, `id`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`remote_service_name`) COMMENT 'for getTraces and getRemoteServiceNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';
CREATE TABLE IF NOT EXISTS zipkin_annotations (
`trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
`span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id',
`a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
`a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
`a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
`a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
`endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null',
`endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
`endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',
`endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces and autocomplete values';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces and autocomplete values';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job';
CREATE TABLE IF NOT EXISTS zipkin_dependencies (
`day` DATE NOT NULL,
`parent` VARCHAR(255) NOT NULL,
`child` VARCHAR(255) NOT NULL,
`call_count` BIGINT,
`error_count` BIGINT,
PRIMARY KEY (`day`, `parent`, `child`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
3)、效果
启动微服务,执行controller请求,看是否成功。
RabbitMQ
zipkin
MySQL
至此,springcloud sleuth + zipkin + rabbitmq + mysql 就全部整合成功了!
总结
微服务的治理方案有很多,学习方向根据个人喜好决定,我的经验就是不必盲目跟从这种用于辅助的方案,比如现在有SkyWalking,以后可能还有SkyFlying、SkySwimming。
走向高级软件工程师都要有一个意识,就是在层出不穷的开源框架如雨后春笋般出现的时候,你得有信心用到哪个花点时间就能自己搭建起来,这才是提升自己的最有效方法。
一个项目使用什么治理方案最重要的绝不是跟风,而是哪款最适合就用哪款,就像你找女朋友一样,不单单是找漂亮的,而是找最能一起过日子的,否则就是貌合神离。
分享
本篇实际上是我8年多工作及学习过程中在云笔记中记录的内容之一,其实还有很多我闲暇之余都做了下整理,有感兴趣的朋友可以私信我获取,什么时候用到了翻开说不定就能节省很多时间。
本人原创文章纯手打,专注于分享主流技术及实际工作经验,觉得有一滴滴帮助的话就请点个推荐吧!
「Java分享客栈」随时用随时翻:微服务链路追踪之zipkin搭建的更多相关文章
- 「Java分享客栈」Nacos配置中心称王称霸,我Apollo一生也不弱于人!
前言 Apollo又称阿波罗配置中心,在前两年还是挺火的,但阿里SpringCloud套件席卷国内之后,nacos就成为了最被亲睐的分布式配置中心,nacos是配置中心和注册中心二合一的产品,单纯功能 ...
- 【Java分享客栈】我为什么极力推荐XXL-JOB作为中小厂的分布式任务调度平台
前言 大家好,我是福隆苑居士,今天给大家聊聊XXL-JOB的使用. XXL-JOB是本人呆过的三家公司都使用到的分布式任务调度平台,前两家都是服务于传统行业(某大型移动基地和某大型电网),现在 ...
- 【Java分享客栈】SpringBoot整合WebSocket+Stomp搭建群聊项目
前言 前两周经常有大学生小伙伴私信给我,问我可否有偿提供毕设帮助,我说暂时没有这个打算,因为工作实在太忙,现阶段无法投入到这样的领域内,其中有两个小伙伴又问到我websocket该怎么使用,想给自己的 ...
- 【Java分享客栈】一文搞定CompletableFuture并行处理,成倍缩短查询时间。
前言 工作中你可能会遇到很多这样的场景,一个接口,要从其他几个service调用查询方法,分别获取到需要的值之后再封装数据返回. 还可能在微服务中遇到类似的情况,某个服务的接口,要使用好几次f ...
- 【Java分享客栈】一文搞定京东零售开源的AsyncTool,彻底解决异步编排问题。
一.前言 本章主要是承接上一篇讲CompletableFuture的文章,想了解的可以先去看看案例: https://juejin.cn/post/7091132240574283813 Comple ...
- 【Java分享客栈】SpringBoot线程池参数搜一堆资料还是不会配,我花一天测试换你此生明白。
一.前言 首先说一句,如果比较忙顺路点进来的,可以先收藏,有时间或用到了再看也行: 我相信很多人会有一个困惑,这个困惑和我之前一样,就是线程池这个玩意儿,感觉很高大上,用起来很fashion, ...
- 【Java分享客栈】超简洁SpringBoot使用AOP统一日志管理-纯干货干到便秘
前言 请问今天您便秘了吗?程序员坐久了真的会便秘哦,如果偶然点进了这篇小干货,就麻烦您喝杯水然后去趟厕所一边用左手托起对准嘘嘘,一边用右手滑动手机看完本篇吧. 实现 本篇AOP统一日志管理写法来源于国 ...
- Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战
Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战 说明: Java生鲜系统中微服务的拆分应该如何架构设计与分析呢?以下是我的实战中的设计与经验分析. 目录 1. 微服务简介2. 当前现状3. ...
- 「 从0到1学习微服务SpringCloud 」08 构建消息驱动微服务的框架 Spring Cloud Stream
系列文章(更新ing): 「 从0到1学习微服务SpringCloud 」01 一起来学呀! 「 从0到1学习微服务SpringCloud 」02 Eureka服务注册与发现 「 从0到1学习微服务S ...
随机推荐
- Numpy对数组按索引查询
Numpy对数组按索引查询 三种索引方法: 基础索引 神奇索引 布尔索引 基础索引 一维数组 和Python的List一样 二维数组 注意:切片的修改会修改原来的数组 原因:Numpy经常要处理大数组 ...
- 用jq实现移动端滑动轮播以及定时轮播效果
Html的代码: <div class="carousel_img"> <div class="car_img" style="ba ...
- 解决 Tomcat 控制台输出乱码(Tomcat Localhost Log / Tomcat Catalina Log 乱码)
1. 按下图修改 先找到你的 Tomcat 安装目录,然后进入conf文件夹,找到 logging.properties,并打开它,然后把所有 UTF-8 格式的编码改成 GBK即可,具体操作如下图
- js知识梳理3:创建对象的模式探究
写在前面 注:这个系列是本人对js知识的一些梳理,其中不少内容来自书籍:Javascript高级程序设计第三版和JavaScript权威指南第六版,感谢它们的作者和译者.有发现什么问题的,欢迎留言指出 ...
- kali添加开机自启[亲测有效]
kali添加开机自启 采用systemd的方法,kali默认是没有rc.local的,需要自己创建.本方法也适用于ubuntu 18.04 64bit 改写rc-local.service 文件 先从 ...
- 帝国CMS只备份栏目和模板的方法
方法一:不备份所有帝国cms数据内容表 我们知道帝国cms有8大模型,分别是 1.新闻系统数据表 ( phome_ecms_news )2.下载系统数据表 ( phome_ecms_download ...
- Cookie&&Session&&jsp入门
会话技术 会话:一次会话中包含多次请求和响应. 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止 功能:在一次会话的范围内的多次请求间,共享数据 方式: 客户端会话技术:Coo ...
- Java学习day42
继续刷力扣题
- Java中日期格式化的实现算法
package com.study.test; import java.io.Serializable; import java.text.SimpleDateFormat; import java. ...
- ASP.NETCore统一处理404错误都有哪些方式?
当未找到网页并且应用程序返回 404 错误时,ASP.NET Core MVC 仅呈现通用浏览器错误页面,如下图所示 这不是很优雅,是吗? 我们平时看到的404页面一般是这样的 还有这样的 试了下京东 ...