概述
为什么需要链路追踪
微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性,如果出现了错误和异常,很难去定位。主要体现在,一个请求可能需要调用很多个服务,而内部服务的调用复杂性,决定了问题难以定位。所以微服务架构中,必须实现分布式链路追踪,去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而达到每个请求的步骤清晰可见,出了问题,很快定位。
Zipkin介绍
Zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于Google Dapper的论文设计而来,由 Twitter公司开发贡献。其主要功能是聚集来自各个异构系统的实时监控数据,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。除了面向开发的 API 接口之外,它也提供了方便的 UI 组件帮助我们直观的搜索跟踪信息和分析请求链路明细。
Spring Cloud Sleuth+ Zipkin的作用
Spring Cloud Sleuth 为服务之间调用提供链路追踪。通过 Sleuth 可以很清楚的了解到一个服务请求经过了哪些服务,每个服务处理花费了多长。从而让我们可以很方便的理清各微服务间的调用关系、优化比较耗时的服务、排查一下出故障的服务。
耗时分析: 通过 Sleuth 可以很方便的了解到每个采样请求的耗时,从而分析出哪些服务调用比较耗时;
可视化错误: 对于程序未捕捉的异常,可以通过集成 Zipkin 服务界面上看到;
链路优化: 对于调用比较频繁的服务,可以针对这些服务实施一些优化措施。
Spring Cloud Sleuth 可以结合 Zipkin,将信息发送到 Zipkin,利用 Zipkin 的存储来存储信息,利用 Zipkin UI 来展示数据。
Zipkin Server 安装启动
在SpringBoot2.0之前的版本,Zipkin服务端,也就是可视化界面,需要自己新建项目引入依赖搭建,如同搭建eureka注册中一样。
但是在SpringBoot2.0之后的版本,官方提供好了jar包(Zipkin服务端),直接下载使用java -jar xxx.jar即可运行,不需要再手动搭建了。
下载zipkin-server
直接在官网可下载:https://zipkin.io/pages/quickstart.html
如图:
笔者下载的版本是:zipkin-server-2.23.2-exec.jar
启动zipkin-server
然后在控制台切换放置jar包的目录执行下面命令:
java -jar zipkin-server-2.23.2-exec.jar
启动如图:
控制台访问:http://localhost:9411/zipkin/,如图:
到这里zipkin-server就搭建好了。
示例说明
我们采用三个服务示例来说明调用链路
zx-eureka(不做任何改动,直接启动)
请点击了解:SpringCloud注册中心Eureka
zx-feign-service(之前基础上修改)
zx-feign-client(之前基础上修改)
请点击了解:SpringCloud之Feign的组件使用
zx-springcloud-sleuth(新建)
说明:本文的示例采用的zipkin的web方式。
1. 改造zx-feign-service
增加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
application.yml增加配置
spring:
#zipkin服务端地址(sleuth-cli收集信息后通过http传输到zinkin-server)
zipkin:
#数据上传至zipkin服务端的地址
base-url: http://127.0.0.1:9411/
#设置成false,表示这只是一个URL地址而不是服务名称(nacos与zipkin一起使用时可能出现此问题,这里可忽略)
#discoveryClientEnabled: false
#发送数据类型 kafaka、rabbitmq、web
sender:
type: WEB
#全部采集,默认的采样比例为: 0.1(即10%),1.0则表示全部采集
sleuth:
sampler:
probability: 1.0
DemoApiController修改最终如下
@RestController
@RequestMapping("/api/demo")
public class DemoApiController {
private static final Logger logger = LoggerFactory.getLogger(DemoApiController.class);
@Value("${server.port}")
private String port;
@Value("${spring.application.name}")
private String applicationName;
@GetMapping("getData")
public String getData(String id) {
logger.info("/api/demo/getData id:{}",id);
return applicationName+":"+port+",接收到参数id:"+id;
}
/**
* 用于测试zipkin的
* @param id
* @return
*/
@GetMapping("getZipkinData")
public String getZipkinData(String id) {
logger.info("/api/demo/getZipkinData id:{}",id);
return "调用服务:"+applicationName+",端口:"+port+",参数id:"+id;
}
}
2. 改造zx-feign-client
增加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
application.yml增加配置
spring:
#zipkin服务端地址(sleuth-cli收集信息后通过http传输到zinkin-server)
zipkin:
#数据上传至zipkin服务端的地址
base-url: http://127.0.0.1:9411/
#设置成false,表示这只是一个URL地址而不是服务名称(nacos与zipkin一起使用时可能出现此问题,这里可忽略)
#discoveryClientEnabled: false
#发送数据类型 kafaka、rabbitmq、web
sender:
type: WEB
#全部采集,默认的采样比例为: 0.1(即10%),1.0则表示全部采集
sleuth:
sampler:
probability: 1.0
在zx-feign-client的feign调用类中增加调用zx-feign-service的新方法
DemoFeignClient类改造
@GetMapping("/api/demo/getZipkinData")
String getZipkinData(@RequestParam("id") String id);
DemoFeignClientHystric改造
@Override
public String getZipkinData(String id) {
logger.info("DemoFeignClientHystric->getZipkinData熔断了");
return "";
}
DemoController修改最终如下
@RestController
@RequestMapping("/demo")
public class DemoController {
private static final Logger logger = LoggerFactory.getLogger(DemoController.class);
@Value("${server.port}")
private String port;
@Value("${spring.application.name}")
private String applicationName;
@Autowired
private DemoFeignClient demoFeignClient;
@GetMapping("getData")
public String getData(String id) {
logger.info("/demo/getData id:{}",id);
String result = demoFeignClient.getData(id);
logger.info("调用feign服务方的结果:{}",result);
return "调用feign服务方的数据是:"+result;
}
/**
* 用于测试zipkin的
* @param id
* @return
*/
@GetMapping("getZipkinData")
public String getZipkinData(String id) {
logger.info("/demo/getZipkinData id:{}",id);
String result = demoFeignClient.getZipkinData(id);
logger.info("/demo/getZipkinData 调用feign服务方的结果:{}",result);
return "调用服务:"+applicationName+",端口:"+port+",参数id:"+id+"; >>>>>> feign调用返回的结果:"+result;
}
3. 新建zx-springcloud-sleuth
引入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 服务链路追踪(Spring Cloud Sleuth) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
bootstrap.yml
spring:
application:
name: zx-springcloud-sleuth
application.yml
server:
port: 9008
logging:
config: classpath:logback.xml
eureka:
client:
healthcheck:
enabled: true
service-url:
defaultZone: http://zxdemo:zxdemopwd@127.0.0.1:8002/eureka/
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
feign:
hystrix:
enabled: true
spring:
#zipkin服务端地址(sleuth-cli收集信息后通过http传输到zinkin-server)
zipkin:
#数据上传至zipkin服务端的地址
base-url: http://127.0.0.1:9411/
#设置成false,表示这只是一个URL地址而不是服务名称(nacos与zipkin一起使用时可能出现此问题,这里可忽略)
#discoveryClientEnabled: false
#发送数据类型 kafaka、rabbitmq、web
sender:
type: WEB
#全部采集,默认的采样比例为: 0.1(即10%),1.0则表示全部采集
sleuth:
sampler:
probability: 1.0
zx-springcloud-sleuth进行feign调用zx-feign-client
DemoFeignClient接口
import com.zx.springcloud.sleuth.demo.feign.impl.DemoFeignClientHystric;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "zx-feign-client",fallback = DemoFeignClientHystric.class)
public interface DemoFeignClient {
@GetMapping("/demo/getZipkinData")
String getZipkinData(@RequestParam("id") String id);
}
feign熔断类DemoFeignClientHystric
import com.zx.springcloud.sleuth.demo.feign.DemoFeignClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class DemoFeignClientHystric implements DemoFeignClient {
private static final Logger logger = LoggerFactory.getLogger(DemoFeignClientHystric.class);
@Override
public String getZipkinData(String id) {
logger.info("DemoFeignClientHystric->getZipkinData熔断了");
return "";
}
}
编写一个示例Controller
import com.zx.springcloud.sleuth.demo.feign.DemoFeignClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
/**
* demo示例
* @author Nian.Li
* @version 1.0
* @date 2018-05-29
*/
@RestController
@RequestMapping("/api/demo")
public class DemoApiController {
private static final Logger logger = LoggerFactory.getLogger(DemoApiController.class);
@Value("${server.port}")
private String port;
@Value("${spring.application.name}")
private String applicationName;
@Autowired
private DemoFeignClient demoFeignClient;
@GetMapping("/getData/{id}")
public String getData(@PathVariable("id") String id) {
logger.info("/api/demo/getData id:{}",id);
String result = demoFeignClient.getZipkinData(id);
logger.info("/demo/getZipkinData 调用feign服务方的结果:{}",result);
return "调用服务:"+applicationName+",端口:"+port+",参数id:"+id+"; >>>>>> feign调用返回的结果:"+result;
}
}
4. 启动各个服务,依次启动顺序如下:
zx-eureka
zx-feign-service
zx-feign-client
zx-springcloud-sleuth
都启动完成之后,查看注册中心,如图:
5. 访问接口,查看调用链路
访问zx-springcloud-sleuth的接口:http://127.0.0.1:9008/api/demo/getData/11111,如图:
点击Zipkin Server界面的 "Run Query"按钮查看Zipkin上的数据,如图:
我们再切换到Zipkin的依赖(dependency),如图:
本文项目源码地址:
https://github.com/cdzxkj/zx_springcloud_demo
转载请注明来自:
https://blog.csdn.net/javanian
欢迎访问博主的独立站:
http://www.muzijinxin.com/
最后
以上就是呆萌金毛为你收集整理的SpringCloud链路追踪Spring Cloud Sleuth + Zipkin的全部内容,希望文章能够帮你解决SpringCloud链路追踪Spring Cloud Sleuth + Zipkin所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复