文档章节

使用Spring Cloud Sleuth实现链路监控

SpringForAll
 SpringForAll
发布于 2017/11/10 10:58
字数 1984
阅读 3917
收藏 180

作者:社区 徐靖峰 原文地址:http://www.spring4all.com/article/156

在服务比较少的年代,一个系统的接口响应缓慢通常能够迅速被发现,但如今的微服务模块,大多具有规模大,依赖关系复杂等特性,错综复杂的网状结构使得我们不容易定位到某一个执行缓慢的接口。分布式的服务跟踪组件就是为了解决这一个问题。其次,它解决了另一个难题,在没有它之前,我们客户会一直询问:你们的系统有监控吗?你们的系统有监控吗?你们的系统有监控吗?现在,谢天谢地,他们终于不问了。是有点玩笑的成分,但可以肯定的一点是,实现全链路监控是保证系统健壮性的关键因子。

介绍Spring Cloud Sleuth和Zipkin的文章在网上其实并不少,所以我打算就我目前的系统来探讨一下,如何实现链路监控。全链路监控这个词意味着只要是不同系统模块之间的调用都应当被监控,这就包括了如下几种常用的交互方式:

1 Http协议,如RestTemplate,Feign,Okhttp3,HttpClient...

2 Rpc远程调用,如Motan,Dubbo,GRPC...

3 分布式Event,如RabbitMq,Kafka...

而我们项目目前混合使用了Http协议,Motan Rpc协议,所以本篇文章会着墨于实现这两块的链路监控。

项目结构

项目结构

上面的项目结构是本次demo的核心结构,其中

  1. zipkin-server作为服务跟踪的服务端,记录各个模块发送而来的调用请求,最终形成调用链路的报告。
  2. order,goods两个模块为用来做测试的业务模块,分别实现了http形式和rpc形式的远程调用,最终我们会在zipkin-server的ui页面验证他们的调用记录。
  3. interface存放了order和goods模块的公用接口,rpc调用需要一个公用的接口。
  4. filter-opentracing存放了自定义的motan扩展代码,用于实现motan rpc调用的链路监控。

Zipkin服务端

添加依赖

全部依赖

核心依赖

<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-server</artifactId>
</dependency>
<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-autoconfigure-ui</artifactId>
</dependency>
<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-storage-mysql</artifactId>
    <version>1.28.0</version>
</dependency>

zipkin-autoconfigure-ui提供了默认了UI页面,zipkin-storage-mysql选择将链路调用信息存储在mysql中,更多的选择可以有elasticsearchcassandra

zipkin-server/src/main/resources/application.yml

spring:
  application:
    name: zipkin-server
  datasource:
    url: jdbc:mysql://localhost:3306/zipkin
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
zipkin:
   storage:
      type: mysql
server:
  port: 9411

创建启动类

@SpringBootApplication
@EnableZipkinServer
public class ZipkinServerApp {

    @Bean
    public MySQLStorage mySQLStorage(DataSource datasource) {
        return MySQLStorage.builder().datasource(datasource).executor(Runnable::run).build();
    }

    public static void main(String[] args) {
        SpringApplication.run(ZipkinServerApp.class, args);
    }

}

当前版本在手动配置数据库之后才不会启动报错,可能与版本有关。mysql相关的脚本可以在此处下载:mysql初始化脚本

zipkin-server单独启动后,就可以看到链路监控页面了,此时由于没有收集到任何链路调用记录,显示如下:

zipkin服务端页面

HTTP链路监控

编写order和goods两个服务,在order暴露一个http端口,在goods中使用RestTemplate远程调用,之后查看在zipkin服务端查看调用信息。

首先添加依赖,让普通的应用具备收集和发送报告的能力,这一切在spring cloud sleuth的帮助下都变得很简单

添加依赖

全部依赖

核心依赖

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

spring-cloud-starter-zipkin依赖内部包含了两个依赖,等于同时引入了spring-cloud-starter-sleuthspring-cloud-sleuth-zipkin两个依赖。名字特别像,注意区分。

以order为例介绍配置文件

order/src/main/resources/application.yml

spring:
  application:
    name: order # 1
  zipkin:
    base-url: http://localhost:9411 # 2
  sleuth:
    enabled: true
    sampler:
      percentage: 1 # 3
server:
  port: 8060

<1> 指定项目名称可以方便的标记应用,在之后的监控页面可以看到这里的配置名称

<2> 指定zipkin的服务端,用于发送链路调用报告

<3> 采样率,值为[0,1]之间的任意实数,顾名思义,这里代表100%采集报告。

编写调用类

服务端order

@RestController
@RequestMapping("/api")
public class OrderController {

    Logger logger = LoggerFactory.getLogger(OrderController.class);

    @RequestMapping("/order/{id}")
    public MainOrder getOrder(@PathVariable("id") String id) {
        logger.info("order invoking ..."); //<1>
        return new MainOrder(id, new BigDecimal(200D), new Date());
    }
}

客户端goods

public MainOrder test(){
    ResponseEntity<MainOrder> mainOrderResponseEntity = restTemplate.getForEntity("http://localhost:8060/api/order/1144", MainOrder.class);
    MainOrder body = mainOrderResponseEntity.getBody();
    return body;
}

<1> 首先观察这一行日志在控制台是如何输出的

2017-11-08 09:54:00.633  INFO [order,d251f40af64361d2,e46132755dc395e1,true] 2780 --- [nio-8060-exec-1] m.c.sleuth.order.web.OrderController     : order invoking ...

比没有引入sleuth之前多了一些信息,其中order,d251f40af64361d2,e46132755dc395e1,true分别代表了应用名称,traceId,spanId,当前调用是否被采集,关于trace,span这些专业词语,强烈建议去看看Dapper这篇论文,有很多中文翻译版本,并不是想象中的学术范,非常容易理解,很多链路监控文章中的截图都来自于这篇论文,我在此就不再赘述概念了。

紧接着,回到zipkin-server的监控页面,查看变化

应用名称

调用详细记录

依赖关系

到这里,Http监控就已经完成了,如果你的应用使用了其他的Http工具,如okhttp3,也可以去[opentracing,zipkin相关的文档中寻找依赖。

RPC链路监控

虽说spring cloud是大势所趋,其推崇的http调用方式也是链路监控的主要对象,但不得不承认目前大多数的系统内部调用仍然是RPC的方式,至少我们内部的系统是如此,由于我们内部采用的RPC框架是weibo开源的motan,这里以此为例,介绍RPC的链路监控。motan使用SPI机制,实现了对链路监控的支持,https://github.com/weibocom/motan/issues/304这条issue中可以得知其加入了opentracing标准化追踪。但目前只能通过自己添加组件的方式才能配合spring-cloud-sleuth使用,下面来看看实现步骤。

filter-opentracing

实现思路:引入SleuthTracingFilter,作为全局的motan过滤器,给每一次motan的调用打上traceId和spanId,并编写一个SleuthTracingContext,持有一个SleuthTracerFactory工厂,用于适配不同的Tracer实现。

具体的实现可以参考文末的地址

order/src/main/resources/META-INF/services/com.weibo.api.motan.filter.Filter

com.weibo.api.motan.filter.sleuth.SleuthTracingFilter

添加一行过滤器的声明,使得项目能够识别

配置SleuthTracingContext

@Bean
SleuthTracingContext sleuthTracingContext(@Autowired(required = false)  org.springframework.cloud.sleuth.Tracer tracer){
    SleuthTracingContext context = new SleuthTracingContext();
    context.setTracerFactory(new SleuthTracerFactory() {
        @Override
        public org.springframework.cloud.sleuth.Tracer getTracer() {
            return tracer;
        }
    });

    return context;
}

使用spring-cloud-sleuth的Tracer作为motan调用的收集器

为服务端和客户端配置过滤器

basicServiceConfigBean.setFilter("sleuth-tracing");

basicRefererConfigBean.setFilter("sleuth-tracing");

编写调用测试类

order作为客户端

@MotanReferer
GoodsApi goodsApi;

@RequestMapping("/goods")
public String getGoodsList() {
    logger.info("getGoodsList invoking ...");
    return goodsApi.getGoodsList();
}

goods作为服务端

@MotanService
public class GoodsApiImpl implements GoodsApi {

    Logger logger = LoggerFactory.getLogger(GoodsApiImpl.class);

    @Override
    public String getGoodsList() {
        logger.info("GoodsApi invoking ...");
        return "success";
    }
}

查看调用关系

motan调用详细信息

依赖关系

第一张图中,使用前缀http和motan来区别调用的类型,第二张图中,依赖变成了双向的,因为一开始的http调用goods依赖于order,而新增了motan rpc调用之后order又依赖于goods。

总结

系统间交互的方式除了http,rpc,还有另外的方式如mq,以后还可能会有更多的方式,但实现的监控的思路都是一致的,即如何无侵入式地给调用打上标签,记录报告。Dapper给实现链路监控提供了一个思路,而OpenTracing为各个框架不同的调用方式提供了适配接口....Spring Cloud Sleuth则是遵循了Spring一贯的风格,整合了丰富的资源,为我们的系统集成链路监控提供了很大的便捷性。

关于motan具体实现链路监控的代码由于篇幅限制,将源码放在了我的github中,如果你的系统使用了motan,可以用于参考:https://github.com/lexburner/sleuth-starter

参考

《Spring Cloud微服务实战》-- 翟永超

黄桂钱老师的指导

© 著作权归作者所有

共有 人打赏支持
SpringForAll
粉丝 95
博文 11
码字总数 22839
作品 0
加载中

评论(2)

梁某某
梁某某
mq 方式有好的实例或者介绍么?求指点
终曲
终曲
我们已经实验性地用了扩展spi进行追踪,但是都在内部motan版本上,等切到开源版motan估计分布式追踪能成为其默认的组件
史上最简单的 SpringCloud 教程

《史上最简单的 SpringCloud 教程》系列: 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka) 史上最简单的SpringCloud教程 | 第二篇: 服务消费者(rest+ribbon) 史上最...

外星人et59
04/21
0
0
服务链路追踪---Sleuth

Sleuth:日志收集工具包,封装了Dapper和log-based追踪以及Zipkin和HTrace操作,为SpringCloud应用实现了一种分布式追踪解决方案。 当服务与服务之间调用复杂时,SpringCloud Sleuth配合Zip...

dalaoyang
04/26
0
0
SpringCloud实战10-Sleuth

Spring-Cloud-Sleuth是Spring Cloud的组成部分之一,为SpringCloud应用实现了一种分布式追踪解决方案,其兼容了Zipkin, HTrace和log-based追踪,追踪微服务rest服务调用链路的问题,接触到zip...

狂小白
05/30
0
0
这些优秀的 Spring Cloud 开源软件,你知道几个?

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用...

技术小能手
08/30
0
0
SpringCloud--鸿鹄Cloud分布式微服务云系统

简介 鸿鹄云Cloud是基于SpringCloud来封装的,是一系列框架的有序集合。利用Spring Boot的开发模式简化了分布式系统基础设施的开发,如服务发现、注册、配置中心、消息总线、负载均衡、断路器...

itcloud
07/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

用Golang做了一个命令行贪吃蛇游戏

用Golang做了一个命令行贪吃蛇游戏 项目介绍 项目链接:https://gitee.com/lwow2025/snake-go 最近看了一本做几个小项目的书,突然就想用Golang做一个命令行贪吃蛇,也没啥特殊原因。 软件架...

Mediv
15分钟前
0
0
storm的利用并行度提高处理速度的经验

在storm的流计算框架中,在数据量非常大或者计算逻辑比较复杂的情况下,可能会造成处理速度变慢的情况,最后反而不满足了系统的处理要求,因此这里讨论一下。本文的内容是我在storm的使用过程...

飓风2000
24分钟前
0
0
课程推荐|深入浅出区块链博主:全栈区块链开发者的4堂必修课(线上优惠)

Tiny熊从2017年开始更新“深入浅出区块链”博客,在第一篇文章中,关于如何系统学习区块链技术,他这样描述:“从事区块链开发也有很多方向,如:区块链应用开发人员、区块链架构师、底层核心...

HiBlock
36分钟前
0
0
激活win10 亲测有效

1.首先,我们先查看一下Win10正式专业版系统的激活状态: 点击桌面左下角的“Windows”按钮,从打开的扩展面板中依次点击“设置”-“更新和安全”,并切换到“激活”选项卡,在此就可以查看到...

可达鸭眉头一皱
38分钟前
0
0
SpringWind180926

SpringWind SpringWind项目代码学习笔记 /SpringWind/src/main/webapp/WEB-INF/views/login.html 第15行action="#springUrl('/account/login.html')"【为什么是#springUrl】 第4行<a class=......

颖伙虫
50分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部