springcloud使用zipkin实现链路追踪与监控

微服务架构是一种分布式架构,微服务系统按照业务划分服务单元,一个微服务往往会有很多个服务单元,一个请求往往会有很多个单元参与,一旦请求出现异常,想要去定位问题点真心不容易,因此需要有个东西去跟踪请求链路,记录一个请求都调用了哪些服务单元,调用顺序是怎么样的以及在各个服务单元处理的时间长短。常见的服务链路追踪组件有google的dapper、twitter的zipkin、阿里的鹰眼等,它们都是出众的开源链路追踪组件。

分布式链路监控与追踪产生背景

在微服务系统中,随着业务的发展,系统会变得越来越大,那么各个服务之间的调用关系也就变得越来越复杂。一个 HTTP 请求会调用多个不同的微服务来处理返回最后的结果,在这个调用过程中,可能会因为某个服务出现网络延迟过高或发送错误导致请求失败,这个时候,对请求调用的监控就显得尤为重要了。Spring Cloud Sleuth 提供了分布式服务链路监控的解决方案。下面介绍 Spring Cloud Sleuth 整合 Zipkin 的解决方案。

Zipkin框架介绍

Zipkin 是 Twitter 的一个开源项目,它基于 Google Dapper 实现的。我们可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的 REST API 接口来辅助查询跟踪数据以实现对分布式系统的监控程序,从而及时发现系统中出现的延迟过高问题。除了面向开发的 API 接口之外,它还提供了方便的 UI 组件来帮助我们直观地搜索跟踪信息和分析请求链路明细,比如可以查询某段时间内各用户请求的处理时间等。

Zipkin 和 Config 结构类似,分为服务端 Server,客户端 Client,客户端就是各个微服务应用。

下面用一张简图说明zipkin的工作原理
在这里插入图片描述

通过图示很容易知道,其实通过引入zipkin这个组件,就是相当于为各个微服务添加了一道上报服务调用关系的监控应用一样,不同微服务之间的调用都会在zipkin-server中统一管理,然后通过ui进行图形化展示,很容易弄清楚各个服务之间的链路调用关系,更容易排查、定位和解决生产中的问题

Zipkin环境搭建

在 Spring Boot 2.0 版本之后,官方已不推荐自己搭建Zipkin服务端了,而是直接提供了编译好的 jar 包。详情可以查看官网:https://zipkin.io/pages/quickstart.html
注意:zipkin官网已经提供定制了,使用官方jar运行即可。

默认端口号启动zipkin服务

java –jar zipkin.jar 默认端口号; 9411

本地启动成功后,浏览器访问:http://localhost:9411 即可
或者自己指定端口号:java -jar zipkin.jar --server.port=8080

在这里插入图片描述

如何在微服务中整合使用zipkin

其实搭建过程非常简单,只需要在各个微服务中添加如下依赖,并在配置文件中添加两行配置即可,

1、添加依赖

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

2、加入zipkin配置

各个微服务中之前的配置保持不变

#zipkin-server地址
spring.zipkin.base-url=http://localhost:9411/

#接口默认全部采样
spring.sleuth.sampler.probability=1.0

3、模拟微服务之间的调用关系

这里假如有一个业务场景,服务1调用服务2,服务2调用服务3,一个简单的链路,贴上主要代码如下,

服务1:


server.port=8102

#挂载到eureka注册中心中的服务名称,以便被其他的消费者发现与引用
spring.application.name=consumer1

#注册中心名字
eureka.client.service-url.defaultZone=http://localhost:8100/eureka

### 需要将自己的服务注册到eureka上
eureka.client.register-with-eureka=true

####需要检索服务
eureka.client.fetch-registry=true

logging.level.com.congge.controller=info

#微服务调用俩路
spring.zipkin.base-url=http://localhost:9411/

spring.sleuth.sampler.probability=1.0

@RestController
public class ConsumerController {

    // RestTemplate 是有SpringBoot Web组件提供 默认整合ribbon负载均衡器
    // rest方式底层是采用httpclient技术
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 在SpringCloud 中有两种方式调用 rest、fegin(SpringCloud)
     * @return
     */

    @RequestMapping("/getFromProvider")
    public String getFromProvider() {
        // 有两种方式,一种是采用服务别名方式调用,另一种是直接调用 使用别名去注册中心上获取对应的服务调用地址
        String url = "http://PROVIDER1/getServerPort";
        String result = restTemplate.getForObject(url, String.class);
        System.out.println("restTemplate 调用 服务提供者服务 :" + result);
        return result;
    }

}

服务2:


server.port=8101

#挂载到eureka注册中心中的服务名称,以便被其他的消费者发现与引用
spring.application.name=provider1

#注册中心名字
eureka.client.service-url.defaultZone=http://localhost:8100/eureka

### 需要将自己的服务注册到eureka上
eureka.client.register-with-eureka=true

####需要检索服务
eureka.client.fetch-registry=true

logging.level.com.congge.controller=info

#zipkin-server地址
spring.zipkin.base-url=http://localhost:9411/

#接口默认全部采样
spring.sleuth.sampler.probability=1.0
    

@Controller
public class Provider1Controller {

    @Value("${server.port}")
    private String serverPort;

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/getServerPort")
    @ResponseBody
    public String getMember() {

        String url = "http://PROVIDER2/getMsgFromProvider2";
        String result = restTemplate.getForObject(url, String.class);
        System.out.println("restTemplate 调用 第二个服务提供者的服务 服务提供者服务 :" + result);
        return result;

    }

}

服务3:


server.port=8106

#挂载到eureka注册中心中的服务名称,以便被其他的消费者发现与引用
spring.application.name=provider2

#注册中心名字
eureka.client.service-url.defaultZone=http://localhost:8100/eureka

### 需要将自己的服务注册到eureka上
eureka.client.register-with-eureka=true

####需要检索服务
eureka.client.fetch-registry=true

logging.level.com.congge.controller=info

spring.zipkin.base-url=http://localhost:9411/

spring.sleuth.sampler.probability=1.0

@Controller
public class Provider2Controller {

    @GetMapping("/getMsgFromProvider2")
    @ResponseBody
    public String getMsgFromProvider2(){
        return "我是第二个服务提供者";
    }

}

分别启动3个微服务,别忘了启动eureka注册中心,然后浏览器访问微服务1的一个接口,可以看到,服务调用成功,
在这里插入图片描述

这时候我们可以在zipkin的ui控制界面看看效果,可以发现,服务之间的调用关系,服务名称已经清晰展现出来了,同时包括服务之间的调用时常等详细信息以及更细的信息都可以通过控制台看到,
在这里插入图片描述

在这里插入图片描述

如果想深入理解zipkin的服务追踪原理的,大家可以从旁边那个json的格式数据入手进行底层原理探究,这里就不再详诉了,留着大家自己探索,
在这里插入图片描述

本篇到这里就结束了,希望对看到的伙伴有用,最后感谢观看!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章