01--理论

背景

微服务架构上通过业务来划分服务的,通过REST调用,对外暴露的一个接口,这个接口功能可能需要很多个服务协同,如果链路上任何一个服务出现问题,都会导致接口调用失败。

随着业务的不断扩张,服务之间互相调用越复杂。调用链的分析也会越复杂。这就需要监控微服务各个服务的调用情况。

zipkin介绍

1.是分布式跟踪系统(Distributed Tracking System)

监控微服务各个服务的调用情况
        举例
            一个请求A,需要先后调用f1,f2,f3等微服务单元的接口,我们可以通过链路追踪查看f1,f2,f3对应接口的耗时。

2.主要功能

聚集来自各个异构系统的实时监控数据。
    追踪微服务架构下的系统延时问题

3.应用系统需要进行装备(instrument)以向 Zipkin 报告数据
4.Zipkin 的用户界面

可以呈现一幅关联图表,以显示有多少被追踪的请求通过了每一层应用。
    可以查看 Span 的依赖关系
    可以以瀑布图的形式显示了每个 Span 的耗时情况,可以一目了然的看到各个服务的性能状况。
        打开每个 Span,还有更详细的数据以键值对的形式呈现,而且这些数据可以在装备应用的时候自行添加。

5.Zipkin 以 Trace 结构表示对一次请求的追踪,又把每个 Trace 拆分为若干个有依赖关系的 Span。

在微服务架构中,一次用户请求可能会由后台若干个服务负责处理,那么每个处理请求的服务就可以理解为一个 Span(可以包括 API 服务,缓存服务,数据库服务以及报表服务等)。当然这个服务也可能继续请求其他的服务,因此 Span 是一个树形结构,以体现服务之间的调用关系。

ZipKin架构

1.跟踪器(Tracer)位于你的应用程序中,并记录发生的操作的时间和元数据,提供了相应的类库,对用户的使用来说是透明的,收集的跟踪数据称为Span;将数据发送到Zipkin的仪器化应用程序中的组件称为Reporter,Reporter通过几种传输方式之一将追踪数据发送到Zipkin收集器(collector),然后将跟踪数据进行存储(storage),由API查询存储以向UI提供数据。

2.ZipKin可以分为两部分:zipkin server和zipkin client

zipkin server:用来作为数据的采集存储、数据分析与展示

1.Collector

收集器组件,它主要用于处理从外部系统发送过来的跟踪信息,将这些信息转换为Zipkin内部处理的Span格式,以支持后续的存储,分析,展示等功能。

2.Storage

存储接受或收集过来的数据
    当前支持Memory,MySQL,Cassandra,ElasticSearch等
    默认存储在内存中。

3.API(Query)

负责查询Storage中存储的数据,提供简单的JSON API获取数据,主要提供给web UI使用

4.Web UI

UI组件,基于API组件实现的上层应用。
    通过UI组件用户可以方便而有直观地查询和分析跟踪信息。

zipkin client

完成了追踪数据的生成与上报功能

概念和字段说明

1、Trace

Zipkin使用Trace结构表示对一次请求的跟踪
        一次请求可能由后台的若干服务负责处理
            每个服务的处理是一个Span,Span之间有依赖关系
    Trace就是树结构的Span集合

2、Span

每个服务的处理跟踪是一个Span,可以理解为一个基本的工作单元,如下:

//一个Span
{//标记一次请求的跟踪,相关的Spans都有相同的traceId "traceId": "bd7a977555f6b982",//span的名称,一般是接口方法的名称"name": "get-traces",//span id"id": "ebf33e1a81dc6f71",//当前Span的父Span id,通过parentId来保证Span之间的依赖关系,如果没有parentId,表示当前Span为根Span;"parentId": "bd7a977555f6b982",//Span创建时的时间戳。单位是微秒,可能服务器有时钟偏差导致时间错误"timestamp": 1458702548478000,//持续时间,单位是微秒 "duration": 354374,//注解用于及时记录事件;有一组核心注解用于定义RPC请求的开始和结束 "annotations": [{"endpoint": {"serviceName": "zipkin-query","ipv4": "192.168.1.2","port": 9411},"timestamp": 1458702548786000,"value": "cs"}],//二进制注释,旨在提供有关RPC的额外信息。"binaryAnnotations": [{"key": "lc","value": "JDBCSpanStore","endpoint": {"serviceName": "zipkin-query","ipv4": "192.168.1.2","port": 9411}}]
}

3、transport

负责从运输从service收集来的spans,并把这些spans转化为zipkin的通用span,并将其传递到存储层,这种方法是模块化的,允许任何生产者接收任何类型的数据
    zipkin配有HTTP、kafka、scribe三种类型的transport
    instrumentations负责和transport进行交互。

服务追踪流程如下:


┌─────────────┐ ┌───────────────────────┐  ┌─────────────┐  ┌──────────────────┐
│ User Code   │ │ Trace Instrumentation │  │ Http Client │  │ Zipkin Collector │
└─────────────┘ └───────────────────────┘  └─────────────┘  └──────────────────┘│                 │                         │                 │┌─────────┐│ ──┤GET /foo ├─▶ │ ────┐                   │                 │└─────────┘         │ record tags│                 │ ◀───┘                   │                 │────┐│                 │     │ add trace headers │                 │◀───┘│                 │ ────┐                   │                 ││ record timestamp│                 │ ◀───┘                   │                 │┌─────────────────┐│                 │ ──┤GET /foo         ├─▶ │                 ││X-B3-TraceId: aa │     ────┐│                 │   │X-B3-SpanId: 6b  │   │     │           │└─────────────────┘         │ invoke│                 │                         │     │ request   │││                 │                         │     │           │┌────────┐          ◀───┘│                 │ ◀─────┤200 OK  ├─────── │                 │────┐ └────────┘│                 │     │ record duration   │                 │┌────────┐     ◀───┘│ ◀──┤200 OK  ├── │                         │                 │└────────┘       ┌────────────────────────────────┐│                 │ ──┤ asynchronously report span     ├────▶ ││                                ││{                               ││  "traceId": "aa",              ││  "id": "6b",                   ││  "name": "get",                ││  "timestamp": 1483945573944000,││  "duration": 386000,           ││  "annotations": [              ││--snip--                        │└────────────────────────────────┘

简单说明

一个应用的代码发起HTTP get请求,经过Trace框架拦截,然后

把当前调用链的Trace信息添加到HTTP Header里面
    记录当前调用的时间戳
    发送HTTP请求,把trace相关的header信息携带上
    调用结束之后,记录当前调用花费的时间
    然后把上面流程产生的 信息汇集成一个span,把这个span信息上传到zipkin的Collector模块

核心数据结构

1、traceId

标记一次请求的跟踪,相关的Spans都有相同的traceId
    Zipkin将具有相同traceId的span组装成跟踪树来直观的将调用链路图展现在我们面前。

2、id

span的id

3、parentId

当前Span的父Span id,通过parentId来保证Span之间的依赖关系,如果没有parentId,表示当前Span为根Span;

4、name

span的名称,一般是接口方法的名称
    name的作用是让人知道它是哪里采集的span

5、timestamp

Span创建时的时间戳。单位是微秒,可能服务器有时钟偏差导致时间错误

6、duration

持续时间,即span的创建到span完成最终的采集所经历的时间,除去span自己逻辑处理的时间
    该时间段可以理解成对于该跟踪埋点来说服务调用的总耗时

7、annotations

用于定位一个request的开始和结束,cs/sr/ss/cr含有额外的信息,比如说时间点,当这个annotation被记录了,这个RPC也被认为完成了。

7.1、cs: Client Start

表示客户端发起请求,一个span的开始
7.2、cr:Client Received

表示客户端获取到服务端返回信息,一个span的结束
7.3、sr:Server Receive

表示服务端收到请求
7.4、ss:Server Send

表示服务端完成处理,并将结果发送给客户端
7.5、sr-cs:sr的时间-cs的时间

网络延迟

7.6、ss-sr:ss的时间-sr的时间

逻辑处理时间

7.7、cr-cs:cr的时间-cs的时间

整个流程时间

8、binaryAnnotations

业务标注列表,如果某些跟踪埋点需要带上部分业务数据(比如url地址、返回码和异常信息等),可以将需要的数据以键值对的形式放入到这个字段中。

02--安装

下载启动

下载:
https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec启动:
java -jar  zipkin-server-2.12.9-exec.jar

访问

http://localhost:9411

03--Springboot 集成 Zipkin--通过io.zipkin.brave包

微服务及端口

服务名称 端口
service8081 8081
service8082 8082
service8083 8083
service8084 8084
service8085 8085

搭建service8081

1.pom.xml依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>service8081</artifactId><version>0.0.1-SNAPSHOT</version><name>service8081</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><zipkin.version>3.9.0</zipkin.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web-services</artifactId></dependency><!-- zipkin相关 --><dependency><groupId>io.zipkin.brave</groupId><artifactId>brave-core</artifactId><version>${zipkin.version}</version></dependency><dependency><groupId>io.zipkin.brave</groupId><artifactId>brave-spancollector-http</artifactId><version>${zipkin.version}</version></dependency><dependency><groupId>io.zipkin.brave</groupId><artifactId>brave-web-servlet-filter</artifactId><version>${zipkin.version}</version></dependency><dependency><groupId>io.zipkin.brave</groupId><artifactId>brave-apache-http-interceptors</artifactId><version>${zipkin.version}</version></dependency><dependency><groupId>io.zipkin.brave</groupId><artifactId>brave-okhttp</artifactId><version>${zipkin.version}</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.application.properties

# 发给zipkin的服务器名称
zipkin.serviceName=service8081
# zipkin的url地址
zipkin.url=http://localhost:9411
# 连接超时时间
zipkin.connectTimeout=6000
# 读取超时时间
zipkin.readTimeout=6000
# 上传 span 的间隔时间
zipkin.flushInterval=1
# 是否启动压缩
zipkin.compressionEnabled=true
# 采样率,默认为0.1,值越大收集越及时,但性能影响也越大
zipkin.samplerRate=1server.port=8081
server.servlet.context-path=/
spring.application.name=service8081

3.Span收集器配置

package com.example.service8081.business.config;import com.github.kristofa.brave.Brave;
import com.github.kristofa.brave.Brave.Builder;
import com.github.kristofa.brave.EmptySpanCollectorMetricsHandler;
import com.github.kristofa.brave.Sampler;
import com.github.kristofa.brave.SpanCollector;
import com.github.kristofa.brave.http.DefaultSpanNameProvider;
import com.github.kristofa.brave.http.HttpSpanCollector;
import com.github.kristofa.brave.http.HttpSpanCollector.Config;
import com.github.kristofa.brave.okhttp.BraveOkHttpRequestResponseInterceptor;
import com.github.kristofa.brave.servlet.BraveServletFilter;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/**** 配置Span收集器 设置收集器的详细参数,包含超时时间、上传span间隔、以及配置采集率等,进而对收集器进行初始化。* */
@Configuration
public class SpanCollectorConfig {// zipkin的url地址@Value("${zipkin.url}")private String url;// 发给zipkin的服务器名称@Value("${zipkin.serviceName}")private String serviceName;// 连接超时时间@Value("${zipkin.connectTimeout}")private int connecTimeout;// 是否启动压缩@Value("${zipkin.compressionEnabled}")private boolean compressionEnabled;// 上传 span 的间隔时间@Value("${zipkin.flushInterval}")private int flushInterval;// 读取超时时间@Value("${zipkin.readTimeout}")private int readTimeout;// 采样率,默认为0.1,值越大收集越及时,但性能影响也越大@Value("${zipkin.samplerRate}")private float samplerRate;/*** 配置 span 收集器* * @return*/@Beanpublic SpanCollector spanCollector() {Config config = Config.builder()//连接超时时间.connectTimeout(connecTimeout)//是否启动压缩.compressionEnabled(compressionEnabled)//上传 span 的间隔时间.flushInterval(flushInterval)//读取超时时间.readTimeout(readTimeout).build();//url:zipkin的url地址return HttpSpanCollector.create(url, config, new EmptySpanCollectorMetricsHandler());}/*** 配置采集率* 作为各调用链路,只需要负责将指定格式的数据发送给zipkin* @param spanCollector* @return*/@Beanpublic Brave brave(SpanCollector spanCollector) {//被采集的服务名称Builder builder = new Builder(serviceName);//采集器builder.spanCollector(spanCollector)//采样率,默认为0.1,值越大收集越及时,但性能影响也越大.traceSampler(Sampler.create(samplerRate)).build();return builder.build();}/*** @Description: 设置server的(服务端收到请求和服务端完成处理,并将结果发送给客户端)过滤器* @Param:* @return: 过滤器*/@Beanpublic BraveServletFilter braveServletFilter(Brave brave) {BraveServletFilter filter = new BraveServletFilter(brave.serverRequestInterceptor(),brave.serverResponseInterceptor(), new DefaultSpanNameProvider());return filter;}/*** @Description: 设置client的 rs(表示服务端收到请求)和cs(表示客户端发起请求)的拦截器* @Param:* @return: OkHttpClient 返回请求实例*/@Beanpublic OkHttpClient okHttpClient(Brave brave) {OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(new BraveOkHttpRequestResponseInterceptor(brave.clientRequestInterceptor(),brave.clientResponseInterceptor(), new DefaultSpanNameProvider())).build();return httpClient;}
}

4.HelloController

package com.example.service8081.business.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;import java.io.IOException;/*** 描述该类* * @class: HelloController* @see*/
@RestController
@RequestMapping("zipkin")
public class HelloController {public static final String url = "http://localhost:8082/zipkin/service2";@AutowiredOkHttpClient client;@GetMapping("/service1")public String service() throws IOException {System.out.println("-----调用service1-----");Request request = new Request.Builder().url(url).build();Response response = client.newCall(request).execute();return "service1," + response.body().string();}
}

service8082到service8085的配置:

1、application.properties 修改

zipkin.serviceName= 改为自己的服务名称
server.port=改为自己的端口
spring.application.name=改为自己的服务名称

2、HelloController 修改

2.1、service8081

@RestController
@RequestMapping("zipkin")
public class HelloController {public static final String url = "http://localhost:8082/zipkin/service2";@AutowiredOkHttpClient client;@GetMapping("/service1")public String service() throws IOException {System.out.println("-----调用service1-----");Request request = new Request.Builder().url(url).build();Response response = client.newCall(request).execute();return "service1," + response.body().string();}
}

2.2、service8082

@RestController
@RequestMapping("zipkin")
public class HelloController {public static final String url = "http://localhost:8083/zipkin/service3";public static final String url2 = "http://localhost:8084/zipkin/service4";@AutowiredOkHttpClient client;@GetMapping("/service2")public String service() throws Exception {System.out.println("-----调用service2-----");Request request1 = new Request.Builder().url(url).build();Request request2 = new Request.Builder().url(url2).build();Response response1 = client.newCall(request1).execute();Response response2 = client.newCall(request2).execute();return "service2【来自service3的信息:" + response1.body().string() +",来自service4的信息:"+ response2.body().string() + "】";}
}

2.3、service8083

@RestController
@RequestMapping("zipkin")
public class HelloController {public static final String url = "http://localhost:8084/zipkin/service4";@AutowiredOkHttpClient client;@GetMapping("/service3")public String service() throws Exception {System.out.println("-----调用service3-----");Request request = new Request.Builder().url(url).build();Response response = client.newCall(request).execute();return "service3," + response.body().string();}
}

2.4、service8084

@RestController
@RequestMapping("zipkin")
public class HelloController {public static final String url = "http://localhost:8086/zipkin/service5";@AutowiredOkHttpClient client;@GetMapping("/service4")public String service() throws Exception {System.out.println("-----调用service4-----");Request request = new Request.Builder().url(url).build();Response response = client.newCall(request).execute();return "service4," + response.body().string();}
}

2.5、service8086

@RestController
@RequestMapping("zipkin")
public class HelloController {@GetMapping("/service5")public String service() throws Exception {System.out.println("-----调用service5-----");return "service5";}
}

测试和分析

http://127.0.0.1:8081/zipkin/service1http://localhost:9411

1、发送请求

2、分析

spans分析

参数说明

调用测试

json样例数据

[{"traceId": "2ce03196265e9729","parentId": "ce0b83f6e721e97d","id": "f470b5a720074acd","kind": "CLIENT","name": "get","timestamp": 1630251666804000,"duration": 1701000,"localEndpoint": {"serviceName": "service8082","ipv4": "192.168.207.1"},"tags": {"http.url": "http://localhost:8083/zipkin/service3"}},{"traceId": "2ce03196265e9729","parentId": "074e4cb45a59a76c","id": "96fde753cf354c3e","kind": "CLIENT","name": "get","timestamp": 1630251667658000,"duration": 747000,"localEndpoint": {"serviceName": "service8084","ipv4": "192.168.207.1"},"tags": {"http.url": "http://localhost:8086/zipkin/service5"}},{"traceId": "2ce03196265e9729","parentId": "f470b5a720074acd","id": "074e4cb45a59a76c","kind": "SERVER","name": "get","timestamp": 1630251667451000,"duration": 988000,"localEndpoint": {"serviceName": "service8084","ipv4": "192.168.207.1"},"tags": {"http.status_code": "200","http.url": "/zipkin/service4"}},{"traceId": "2ce03196265e9729","parentId": "074e4cb45a59a76c","id": "96fde753cf354c3e","kind": "SERVER","name": "get","timestamp": 1630251668029000,"duration": 374000,"localEndpoint": {"serviceName": "service8086","ipv4": "192.168.207.1"},"tags": {"http.status_code": "200","http.url": "/zipkin/service5"}},{"traceId": "2ce03196265e9729","parentId": "3e2b6810b608afc7","id": "8803d668b0b3d243","kind": "SERVER","name": "get","timestamp": 1630251668847000,"duration": 3000,"localEndpoint": {"serviceName": "service8086","ipv4": "192.168.207.1"},"tags": {"http.status_code": "200","http.url": "/zipkin/service5"}},{"traceId": "2ce03196265e9729","parentId": "f470b5a720074acd","id": "074e4cb45a59a76c","kind": "CLIENT","name": "get","timestamp": 1630251667196000,"duration": 1247000,"localEndpoint": {"serviceName": "service8083","ipv4": "192.168.207.1"},"tags": {"http.url": "http://localhost:8084/zipkin/service4"}},{"traceId": "2ce03196265e9729","parentId": "ce0b83f6e721e97d","id": "f470b5a720074acd","kind": "SERVER","name": "get","timestamp": 1630251667042000,"duration": 1459000,"localEndpoint": {"serviceName": "service8083","ipv4": "192.168.207.1"},"tags": {"http.status_code": "200","http.url": "/zipkin/service3"}},{"traceId": "2ce03196265e9729","parentId": "2ce03196265e9729","id": "ce0b83f6e721e97d","kind": "CLIENT","name": "get","timestamp": 1630251666391000,"duration": 2511000,"localEndpoint": {"serviceName": "service8081","ipv4": "192.168.207.1"},"tags": {"http.url": "http://localhost:8082/zipkin/service2"}},{"traceId": "2ce03196265e9729","id": "2ce03196265e9729","kind": "SERVER","name": "get","timestamp": 1630251666347000,"duration": 2562000,"localEndpoint": {"serviceName": "service8081","ipv4": "192.168.207.1"},"tags": {"http.status_code": "200","http.url": "/zipkin/service1"}},{"traceId": "2ce03196265e9729","parentId": "ce0b83f6e721e97d","id": "3e2b6810b608afc7","kind": "CLIENT","name": "get","timestamp": 1630251668505000,"duration": 347000,"localEndpoint": {"serviceName": "service8082","ipv4": "192.168.207.1"},"tags": {"http.url": "http://localhost:8084/zipkin/service4"}},{"traceId": "2ce03196265e9729","parentId": "2ce03196265e9729","id": "ce0b83f6e721e97d","kind": "SERVER","name": "get","timestamp": 1630251666651000,"duration": 2243000,"localEndpoint": {"serviceName": "service8082","ipv4": "192.168.207.1"},"tags": {"http.status_code": "200","http.url": "/zipkin/service2"}},{"traceId": "2ce03196265e9729","parentId": "3e2b6810b608afc7","id": "8803d668b0b3d243","kind": "CLIENT","name": "get","timestamp": 1630251668511000,"duration": 339000,"localEndpoint": {"serviceName": "service8084","ipv4": "192.168.207.1"},"tags": {"http.url": "http://localhost:8086/zipkin/service5"}},{"traceId": "2ce03196265e9729","parentId": "ce0b83f6e721e97d","id": "3e2b6810b608afc7","kind": "SERVER","name": "get","timestamp": 1630251668510000,"duration": 342000,"localEndpoint": {"serviceName": "service8084","ipv4": "192.168.207.1"},"tags": {"http.status_code": "200","http.url": "/zipkin/service4"}}
]

zipkin学习20210819相关推荐

  1. zipkin学习--01--理论

    zipkin学习–01–理论 一.zipkin介绍 是分布式跟踪系统(Distributed Tracking System) 监控微服务各个服务的调用情况 举例:一个请求A,需要先后调用f1,f2, ...

  2. 记微服务架构实战学习笔记

    架构演进和分布式系统基础知识 1.传统架构演进到分布式架构 简介:讲解单机应用和分布式应用架构演进基础知识 (画图) 高可用 LVS+keepalive 1.单体应用:开发速度慢启动时间长依赖庞大等等 ...

  3. 一起读Apache ServiceComb

    喜欢我,就点个Star吧~ https://github.com/apache?q=servicecomb 入门必读: 必读1:首个Apache微服务顶级项目毕业 必读2:致微服务开发者的一封信(一周 ...

  4. 基于事件驱动的微服务教程

    基于事件驱动的微服务教程 使用 Spring Boot.Spring Cloud.Kafka 和 Elasticsearch 掌握具有模式的事件驱动微服务架构 课程英文名:Event-Driven M ...

  5. SpringCloud课程总结 Netflix 系列总结

    SpringCloud课程总结 第一章 课程介绍和学习路线 1.微服务架构SpringCloud课程介绍     简介:课程介绍和课程大纲讲解,讲课风格和重点内容理解技巧 2.技术选型和学后水平    ...

  6. motan yar php,motan学习笔记 六 opentracing Brave+zipkin实现-Go语言中文社区

    前面我们学习了,opentracing的接口定义 本文来学习motan用filter 来拦截请求,并用brace来实现,上报数据到zipkin zipkin是什么 本文主要讲brace 如何实现ope ...

  7. java 父子线程 调用链_ZipKin原理学习--Zipkin多线程及线程池中追踪一致性问题解决...

    在学习Zipkin分布式追踪系统中我们了解到Trace在整个调用链是一致的,在web服务中可以通过在header设置Trace值在不同的服务中进行传递,那样在一个服务内部不同的线程,甚至是线程池中Zi ...

  8. spring cloud学习进阶篇:Spring Cloud Sleuth + Zipkin 实现分布式跟踪解决方案

    2019独角兽企业重金招聘Python工程师标准>>> 简述 使用 spring cloud 用到最多的是各种rest服务调用,Twitter的Zipkin 是一种实现分布式跟踪解决 ...

  9. 服务链路追踪配置mysql_学习微服务的服务链路追踪——Spring Cloud Sleuth+zipkin

    spring cloud sleuth提供了服务链路追踪,并兼容了zipkin,Zipkin是一个链路跟踪工具,可以用来监控微服务集群中调用链路的通畅情况. 1.本来想新建一个有关zipkin-ser ...

最新文章

  1. VC编写自己构造http协议数据的post上传图片类(MFC环境 带编码转换)(转)
  2. 交付效率提升40%,珍爱网基于微服务的DevOps落地指南
  3. 简单理解Tomasulo算法与重加载缓冲区
  4. java设计模式初探之装饰者_JAVA设计模式初探之装饰者模式
  5. python里的pip有什么用_python的pip有什么用
  6. Leave the world behind,山巅雪莲的再次绽放
  7. vue的一点初级理解
  8. java jwks_OIDC中JWK,JWKS的介绍与使用
  9. 基于SpringBoot的后台管理系统(启动类解析,开源的世界真好)(一)
  10. 8086可以用c语言编程吗,[求助]如何将C程序反汇编成8086汇编程序
  11. Tp5.0 PHPMailer邮件发送
  12. C#.NET生成条形码(Code39和Code128)
  13. 【CF335E】 Counting Skyscrapers(期望)
  14. 使用网络图展示Venn图集合及Cytoscape操作视频
  15. 知识蒸馏 | 知识蒸馏理论篇
  16. 判断两个平面向量之间夹角是顺时针还是逆时针
  17. ARCore⭐四、图片识别
  18. 国密sm2加密算法 前后端加密实现
  19. Win32汇编(SMU—递归子程序)
  20. CSAPP 拆炸弹 中科大实验

热门文章

  1. SQL Server数据库设计规范
  2. 最字头之二:最长公共字串
  3. 基于卡尔曼滤波算法的轨迹跟踪
  4. Python打怪小游戏
  5. Apache服务器的安装
  6. 隐性域名转发html代码,你知道显性URL转发/隐性URL转发记录添加方式吗
  7. 鸿蒙大陆9.1正式版礼包,鸿蒙大陆4.1正式版攻略
  8. 技能梳理21@stm32+oled+声音强度检测+舵机
  9. 如何变化MathType破解版中上下标大小
  10. android 上传图片进度条,Android带进度条的文件上传示例(使用AsyncTask异步任务)...