这篇文章主要讲述服务追踪组件zipkin,Spring Cloud Sleuth集成了zipkin组件。

一、简介

Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案,并且兼容支持了 zipkin,你只需要在pom文件中引入相应的依赖即可。

二、服务追踪分析

微服务架构上通过业务来划分服务的,通过REST调用,对外暴露的一个接口,可能需要很多个服务协同才能完成这个接口功能,如果链路上任何一个服务出现问题或者网络超时,都会形成导致接口调用失败。随着业务的不断扩张,服务之间互相调用会越来越复杂。

随着服务的越来越多,对调用链的分析会越来越复杂。它们之间的调用关系也许如下:

三、术语

  • Span:基本工作单元,例如,在一个新建的span中发送一个RPC等同于发送一个回应请求给RPC,span通过一个64位ID唯一标识,trace以另一个64位ID表示,span还有其他数据信息,比如摘要、时间戳事件、关键值注释(tags)、span的ID、以及进度ID(通常是IP地址) 
    span在不断的启动和停止,同时记录了时间信息,当你创建了一个span,你必须在未来的某个时刻停止它。
  • Trace:一系列spans组成的一个树状结构,例如,如果你正在跑一个分布式大数据工程,你可能需要创建一个trace。
  • Annotation:用来及时记录一个事件的存在,一些核心annotations用来定义一个请求的开始和结束 
    • cs - Client Sent -客户端发起一个请求,这个annotion描述了这个span的开始
    • sr - Server Received -服务端获得请求并准备开始处理它,如果将其sr减去cs时间戳便可得到网络延迟
    • ss - Server Sent -注解表明请求处理的完成(当请求返回客户端),如果ss减去sr时间戳便可得到服务端需要的处理请求时间
    • cr - Client Received -表明span的结束,客户端成功接收到服务端的回复,如果cr减去cs时间戳便可得到客户端从服务端获取回复的所有所需时间 
      将Span和Trace在一个系统中使用Zipkin注解的过程图形化:

将Span和Trace在一个系统中使用Zipkin注解的过程图形化:

四、构建工程

基本知识讲解完毕,下面我们来实战,本文的案例主要有三个工程组成:

1.server-zipkin

它的主要作用使用ZipkinServer 的功能,收集调用数据,并展示;

2.chetxt-service

对外暴露接口

3.gps-service

对外暴露接口

上面两个service可以相互调用,并且只有调用了,server-zipkin才会收集数据的,这就是为什么叫服务追踪了。

新建server-zipkin

pom.xml

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
</dependency> <dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
</dependency>

springboot启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) // 不加红字会出现默认database的错误
@EnableZipkinServer
public class BootApplication {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
}
}

配置文件

server.port=9411

新建chetxt-service

pom.xml

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

配置文件

server.port=8008

spring.zipkin.base-url=http://localhost:9411
spring.application.name=chetxt-service

springboot启动类

@SpringBootApplication
@ComponentScan(basePackages="com.chetxt")//扫描组件
@ServletComponentScan(basePackages="com.chetxt")//扫描拦截器,过滤器
public class BootApplication {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
} @Bean
public RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(10000);
httpRequestFactory.setConnectTimeout(10000);
httpRequestFactory.setReadTimeout(10000);
return new RestTemplate();//httpRequestFactory);
} @Bean // 采样器
public AlwaysSampler defaultSampler(){
return new AlwaysSampler();
}
}

暴露接口

@RestController
@RequestMapping("/v1/vehicleorder")
public class OrderinfoController {
@RequestMapping(value = "/addgps", method = RequestMethod.GET)
// @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
public String addgps(String Appcode) {
// 验证笔录项目
if(Appcode == null || Appcode.equals("")){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return new ZhongruiResult(false, true, "缺少appcode", null, null).toJsonString();
} JSONObject param = new JSONObject();
try {
param.put("appcode", Appcode);
} catch (JSONException e) {
e.printStackTrace();
}

     // resttemplate调用gps-service暴露的接口
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE.toString());//application/json
HttpEntity<String> formEntity = new HttpEntity<String>(param.toString(), headers);
String rtnStr=this.restTemplate.postForObject("http://localhost:8009/gps/order/add", formEntity,String.class); return rtnStr;
}   
@RequestMapping(value = "/xxx", method = RequestMethod.GET)
// @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
public String xxx(String Appcode) {   }
  
}

创建gps-service

pom文件和启动类和上面一样

暴露接口

@RestController
@RequestMapping("/gps/order")
public class OrderinfoController {
public static Logger logger = LoggerFactory.getLogger(OrderinfoController.class); @Autowired
private RestTemplate restTemplate; @Value("${server.port}")
private int port; @RequestMapping(value = "/add", method = RequestMethod.POST, consumes = "application/json", produces = "*/*")
// @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
public String add(@RequestBody RequestAdd param) { // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return new ObjectResult(true, "", JsonUtil.object2JsonString(param), null).toJsonString();
} }

配置文件

server.port=8009

spring.zipkin.base-url=http://localhost:9411
spring.application.name=gps-service

一切准备就绪,下面启动三个微服务。

五、演示

浏览器里输入下面的地址,模拟服务之间调用接口

http://localhost:8008/v1/vehicleorder/addgps?Appcode=112233445566

返回结果,表示调用成功

打开zipkin的追踪网址

http://localhost:9411

点击2 spans那一行

点击链接行,弹出具体信息

上面是成功了的,下面改下代码,让gps-service里的add接口出现访问超时

@Bean
public RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(10000);
httpRequestFactory.setConnectTimeout(10000);
httpRequestFactory.setReadTimeout(10000);
return new RestTemplate(httpRequestFactory);// 设置resttemplate访问10s超时
}
@RequestMapping(value = "/add", method = RequestMethod.POST, consumes = "application/json", produces = "*/*")
// @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
public String add(@RequestBody RequestAdd param) {
// 睡眠30s
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return new ObjectResult(true, "", JsonUtil.object2JsonString(param), null).toJsonString();
}

再次请求地址,报超时错误,这是我们预期的

再去zipkin里看看

点击红色链接进来

再点击查看具体原因

好了,是不是非常棒,再也不用怕服务一多乱套了。

源码在微云。

原文地址:http://blog.csdn.net/forezp/article/details/70162074

参考文章:

spring-cloud-sleuth+zipkin追踪服务实现(一)

spring-cloud-sleuth+zipkin追踪服务实现(二)

spring-cloud-sleuth+zipkin追踪服务实现(三)

Spring Cloud Sleuth服务链路追踪(zipkin)(转)的更多相关文章

  1. Spring Cloud(十三):Spring Cloud Sleuth服务链路追踪(zipkin)(转)

    这篇文章主要讲述服务追踪组件zipkin,Spring Cloud Sleuth集成了zipkin组件. 一.简介 Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案, ...

  2. Spring Cloud Sleuth 服务跟踪 将跟踪信息存储到数据库

    参见上一篇博客:Spring Cloud Sleuth 服务跟踪 参考:zipkin使用mysql保存数据 主要在跟踪服务上配置: 在数据库创建数据库表:(可不创建,在classpath中添加对应的s ...

  3. Spring Cloud 整合分布式链路追踪系统Sleuth和ZipKin实战,分析系统瓶颈

    导读 微服务架构中,是否遇到过这种情况,服务间调用链过长,导致性能迟迟上不去,不知道哪里出问题了,巴拉巴拉....,回归正题,今天我们使用SpringCloud组件,来分析一下微服务架构中系统调用的瓶 ...

  4. Spring Cloud Sleuth服务跟踪

    监控 使用zipkin(https://zipkin.io/) 监控服务构建: (普通的springBoot项目) <!--引入的zipkinServer依赖--> <depende ...

  5. Spring Cloud Sleuth 服务跟踪

    项目结构: 一跟踪服务中心,用于收集和展示跟踪情况. 一个服务提供者. 一个服务消费者. 服务跟踪中心: pom.xml添加如下依赖: <dependency> <groupId&g ...

  6. 分布式链路追踪之Spring Cloud Sleuth+Zipkin最全教程!

    大家好,我是不才陈某~ 这是<Spring Cloud 进阶>第九篇文章,往期文章如下: 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强? openFeign夺命连环9问,这谁受得 ...

  7. Spring Cloud Gateway 没有链路信息,我 TM 人傻了(下)

    本系列是 我TM人傻了 系列第五期[捂脸],往期精彩回顾: 升级到Spring 5.3.x之后,GC次数急剧增加,我TM人傻了 这个大表走索引字段查询的 SQL 怎么就成全扫描了,我TM人傻了 获取异 ...

  8. spring boot 2.0.3+spring cloud (Finchley)7、服务链路追踪Spring Cloud Sleuth

    参考:Spring Cloud(十二):分布式链路跟踪 Sleuth 与 Zipkin[Finchley 版] Spring Cloud Sleuth 是Spring Cloud的一个组件,主要功能是 ...

  9. springcloud(十二):使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪

    随着业务发展,系统拆分导致系统调用链路愈发复杂一个前端请求可能最终需要调用很多次后端服务才能完成,当整个请求变慢或不可用时,我们是无法得知该请求是由某个或某些后端服务引起的,这时就需要解决如何快读定位 ...

随机推荐

  1. imx51-linux的cpuinfo之分析

    这两天客户提出来,我们的平板cat /proc/cpuinfo出来的信息中的serial怎么是0. 客户就是上帝啊,没办法,分析找问题贝. 我们先看一下目前的cat /proc/cpuinfo的信息: ...

  2. 飞思卡尔IMX6处理器的GPIO配置方式

    在linux或android系统中,假如我们要配置飞思卡尔IMX6处理器的GPIO管脚,比如是GPIO_19这个管脚,那么要像这样: [cpp] view plaincopy #define  MX6 ...

  3. 【46】java对象的三个特征(oop)

    对象的三个特征: 对象的行为: 对象有哪些行为和方法 同一个类的实例,由于支持相同的行为具有家族式的特征,对象的行为是由方法定义的. 对象的状态: 施加方法时.对象的响应 每个对象都保存着描述当前特征 ...

  4. HBase快照

    CDH是Cloudera的完全开源分布式Apache Hadoop及相关项目(包括Apache HBase).CDH的当前版本(4.2)引入的一个HBase新特性最近加入到了主干中,允许用户对指定表进 ...

  5. DB Query Analyzer 6.01 is released, SQL Execute Schedule function can be used

       DB Query Analyzer is presented by Master Gen feng, Ma from Chinese Mainland. It has English versi ...

  6. 配置SharePoint环境加域提示网络名不可用[已解决]

    今天去客户给机器做备机,带着装好SharePoint07的机器跑过去了,先做个LAN,然后连上机器开始工作:首先当然是改ip地址,然后都改好了开始加域,加了好几次,发现都不行,提示"指定的网 ...

  7. 《万能数据库查询分析器》实现使用SQL语句直接高效地访问文本文件

    <万能数据库查询分析器>实现使用SQL语句直接高效地访问文本文件 马根峰 (广东联合电子服务股份有限公司, 广州 510300) 摘要    用SQL语句来直接访问文本文件?是在做梦吗? ...

  8. 《转》iOS 平台 Cocos2d-x 项目接入新浪微博 SDK 的坑

    最近在做一个 iOS 的 cocos2d-x 项目接入新浪微博 SDK 的时候被“坑”了,最后终于顺利的解决了.发现网上也有不少人遇到一样的问题,但是能找到的数量有限的解决办法写得都不详细,很难让人理 ...

  9. oracle 11g杀掉锁的sql

    oracle 11g杀掉锁的sql [引用 2013-3-6 17:19:12]     字号:大 中 小 --查询出出现锁的session_idselect session_id from v$lo ...

  10. RocketMQ源码 — 七、 RocketMQ高可用(2)

    上一篇说明了RocketMQ怎么支持broker集群的,这里接着说RocketMQ实现高可用的手段之一--冗余. RocketMQ部署的时候一个broker set会有一个mater和一个或者多个sl ...