Sleuth + ZipKin 实现微服务链路追踪 2022-03-18 程序之旅,记录 暂无评论 880 次阅读 ## Sleuth + ZipKin 实现微服务链路追踪 > 由于微服务架构本身的特性,一个完整的业务逻辑后边有着一些列相对独立的细粒度的服务组成,每个服务由不同的团队开发,且每个服务都分布在不同的机器上,如果在调用的过程发生问题,例如调用失败、调用过程响应很慢或响应失败,我们该如何在这个分布式环境下快速定位问题所在,如何快速分析业务处理中的响应慢的瓶颈在哪?多个微服务的拓扑图关系?如何完整还原一次请求的链路情况? ### 微服务链路追踪 **链路追踪:**运行时通过某种方式记录下服务之间的调用过程,在通过可视化的 UI 界面帮研发运维人员快速定位到出错点。 链路追踪数据的组成:${微服务ID},${Trace ID},${Span ID},${导出标识} - 微服务 ID:说明日志是由哪个微服务产生的 - Trace ID: 轨迹编号。一个完整的业务处理过程被称为轨迹。 - Span ID:步骤编号。一个 TraceId 拥有多个 SpanId,而 SpanId 只能隶属于某一个 TraceId。 - 导出标识:当前这个日志是否被导出,该值为 true 的时候,说明但钱轨迹数据允许被其他链路追踪可视化服务手机展现。 之后通过 Zipkin Server 进行可视化展示。Zipkin 是推特的一个开源项目,它能手机各个服务实例上的链路追踪数据并可视化展示。 ### 基于 Spring Cloud Sleuth 实现链路追踪 当前的实例是 a-service 调用 b-service 之后再调用 c-service。其中 a-service、b-service 和 c-service 是三个微服务程序。 #### 公共相同部分 service 的 maven 依赖如下: ```xml org.springframework.boot spring-boot-starter-web com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery org.springframework.cloud spring-cloud-starter-openfeign ``` 使用的 application.properties 配置 ```properties # 应用名称 spring.application.name=a-service # 应用服务 WEB 访问端口 server.port=7000 # Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html # Nacos认证信息 spring.cloud.nacos.discovery.username=nacos spring.cloud.nacos.discovery.password=nacos # Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 spring.cloud.nacos.discovery.server-addr=192.168.1.102:8848 # 注册到 nacos 的指定 namespace,默认为 public spring.cloud.nacos.discovery.namespace=public # 演示需要 logging.level.root=debug ``` > 其中 maven 的创建过程三个服务一直,application.properties 的配置是 > > server.port=7000 # a:7000/b: 8000/ c:9000 > > 应用名称 > > spring.application.name=a-service # a:a-service/b: b-service/ c:c-service 在所有的启动类头上添加 `@EnableFeignClients `,开启 openfeign 服务功能。 #### 代码实现差异部分 在 **C 工程**中创建 Controller 类 ```java @RestController public class SampleController { @GetMapping("/c") public String methodC() { String result = "->Service C"; return result; } } ``` 在 B 工程中创建调用 C 的客户端接口类和 controller 类。 ```java @FeignClient("c-service") public interface CServiceFeignClient { @GetMapping("/c") public String methodC(); } // controller @RestController public class SampleController { @Resource private CServiceFeignClient cServiceFeignClient; @GetMapping("/b") public String methodB() { String s = cServiceFeignClient.methodC(); String result = "->Service B" + s; return result; } } ``` 在 A 工程中创建调用 B的客户端接口类和 controller 类。 ```java @FeignClient("b-service") public interface BServiceFeignClient { @GetMapping("/b") public String methodB(); } @RestController public class SampleController { @Resource private BServiceFeignClient bServiceFeignClient; @GetMapping("/b") public String methodB() { String s = bServiceFeignClient.methodB(); String result = "->Service A" + s; return result; } } ``` 启动成功后 ![image-20220317225316124](https://mufeng-blog.oss-cn-beijing.aliyuncs.com/typecho/image-20220317225316124.png) 浏览器请求路径:http://localhost:7000/a,此时返回的数据是正确的。 ![image-20220317225522844](https://mufeng-blog.oss-cn-beijing.aliyuncs.com/typecho/image-20220317225522844.png) 所有微服务依赖引入 sleuth,我这里默认导入的版本是 2.2.6.RELEASE。 ```xml org.springframework.cloud spring-cloud-starter-sleuth ``` 重启启动程序后,三个微服务请求的日志内容。 ```tex DEBUG [a-service,bc0577ad385656d0,bc0577ad385656d0,true] 524 --- [nio-7000-exec-1] org.apache.tomcat.util.http.Parameters : Set encoding to UTF-8 DEBUG [b-service,bc0577ad385656d0,2c2c0faf81b966af,true] 5488 --- [nio-8000-exec-1] org.apache.tomcat.util.http.Parameters : Set encoding to UTF-8 DEBUG [c-service,bc0577ad385656d0,ac65c38ee0bc7ccc,true] 12312 --- [nio-9000-exec-1] org.apache.tomcat.util.http.Parameters : Set encoding to UTF-8 ``` ### 构建 Zipkin Server 实现链路追踪的可视化管理 Zipkin 是推特的一个开源项目,基于 Google Dapper 实现,致力于手机服务的定时数据,用于解决微服务框架中的延迟问题,包括数据的收集、存储、查找和展示。 用于对 Sleuth 产生的日志加以手机并采用可视化的数据对链路跟踪进行分析与图表展示。Zipkin 是典型的 C/S 架构模式,需要独立不是 Zipkin 服务器,需要在微服务内部持有 Zipkin 客户端才可以自动实现日志的异步推送与展示。 zipkin 的架构示意 ![zipkin 架构示意图](https://mufeng-blog.oss-cn-beijing.aliyuncs.com/typecho/zipkin%20%E6%9E%B6%E6%9E%84%E7%A4%BA%E6%84%8F%E5%9B%BE.png) #### Zipkin 服务端 在[官网](https://zipkin.io/pages/quickstart.html)中的快速开始中,说明了服务端搭建的方式。 If you have Java 8 or higher installed, the quickest way to get started is to fetch the [latest release](https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=LATEST&c=exec) as a self-contained executable jar: ``` curl -sSL https://zipkin.io/quickstart.sh | bash -s java -jar zipkin.jar ``` 下载完成后启动,默认使用的是 9411 端口,需要注意开启防火墙端口。 #### Zipkin 客户端 1. 在所有的微服务中添加 pom.xml 添加依赖,引入 zipkin 客户端 ```xml org.springframework.cloud spring-cloud-starter-zipkin ``` 2. 在所有的微服务中的 application.properties 配置 zipkin 通讯地址及其采样率 ```properties # sample 采样器。probability:采样率:采集 Trace 的比例,默认是 0.1 spring.sleuth.sampler.probability=1.0 # 每秒采集量,最多 10000 条/秒 trace spring.sleuth.sampler.rate=10000 spring.zipkin.base-url=http://192.168.1.102:9411 ``` - spring.sleuth.sampler.probability:假设在过去的 1 秒产生 10 个 Trace,默认采样率为 0.1 ,也就表示其中 1 条会被发送到 Zipkin 服务端进行分析整理。 - spring.sleuth.sampler.rate:每秒最多的采样量,超出部分直接抛弃。 #### 使用 通过浏览器访问 `http://192.168.1.102:9411`打开 zipkin 的控制台,可以看到微服务间的调用链路。 ![image-20220317234511501](https://mufeng-blog.oss-cn-beijing.aliyuncs.com/typecho/image-20220317234511501.png) PS: Zipkin 的可视化做的不是很好,在实际开发中还是比较推荐 Skywalking。 打赏: 微信, 支付宝 标签: spring cloud, 微服务, 日志, 微服务链路追踪 本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。