文档章节

使用Spring Cloud Sleuth实现链路监控

SpringForAll
 SpringForAll
发布于 2017/11/10 10:58
字数 1984
阅读 3845
收藏 180
点赞 3
评论 2

作者:社区 徐靖峰 原文地址: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

SpringCloud实战10-Sleuth

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

狂小白 ⋅ 05/30 ⋅ 0

服务链路追踪---Sleuth

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

dalaoyang ⋅ 04/26 ⋅ 0

Spring Cloud-honghu Cloud分布式微服务云系统

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

itcloud ⋅ 04/25 ⋅ 0

SpringCloud实战9-Stream消息驱动

官方定义 Spring Cloud Stream 是一个构建消息驱动微服务的框架。   应用程序通过 inputs 或者 outputs 来与 Spring Cloud Stream 中binder 交互,通过我们配置来 binding ,而 Spring Clo...

狂小白 ⋅ 05/29 ⋅ 0

【Spring Cloud】分布式必学springcloud(一)——简介和看法

一、前言 开篇之前,我想说,springcloud会完胜dubbo。 小编以前做分布式是用的webservice、dubbo。最近的项目中,开始使用了springcloud,springcloud包含了很多的组件,这些组件是dubbo没有...

kisscatforever ⋅ 04/16 ⋅ 0

基于 Spring Cloud 的企业级认证与授权 - pig-cloud

基于Spring Cloud、Spring Security Oauth2.0开发企业级认证与授权,提供常见服务监控、链路追踪、日志分析、缓存管理、任务调度等实现。 特点 业务模块不涉及oauth2.0,认证鉴权全部在网关模...

冷冷gg ⋅ 01/07 ⋅ 3

springcloud 高效率本地加Redis双级缓存

在springcloud中我们可以使用spring-boot-starter-data-redis已经为我们处理好分布式缓存,但是我们还是不满足于只存在于网络中传输的缓存,我们现在来扩展成本地加Redis双级缓存,这样就可以...

dounine ⋅ 04/19 ⋅ 0

springcloud架构搭建(一) Eureka服务器搭建及配置

springcloud架构搭建(一) Eureka服务器搭建及配置 今天开始准备学习一下springcloud的相关知识以及环境部署,并且搭建一套springcloud分布式框架: 本文只针对刚开始接触或者没有接触过spr...

itcloud ⋅ 05/21 ⋅ 0

【Spring Cloud】分布式必学springcloud(二)——注册中心Eureka

一、前言 在上一篇博客中,小编简单的向大家介绍了springcloud的一些概念,大家可能对那些还是不太的了解,不过没有问题,盲人摸象嘛,慢慢的摸,你会了解的越来越多的。所以不用担心。在下面...

kisscatforever ⋅ 04/19 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 54分钟前 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 2

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部