SpringBoot如何通过Zipkin实现高效分布式追踪监控?
- 内容介绍
- 文章标签
- 相关推荐
本文共计2890个文字,预计阅读时间需要12分钟。
Zipkin简介:Zipkin是一个分布式追踪系统。它协助收集分析服务架构中处理延迟所需的时间数据。功能包括数据的收集和查询。若你拥有一个低级别的跟踪ID,可直接在Zipkin中查询。
Zipkin 简介
Zipkin is a distributed tracing system. It helps gather timing data needed to troubleshoot latency problems in service architectures. Features include both the collection and lookup of this data.
If you have a trace ID in a log file, you can jump directly to it. Otherwise, you can query based on attributes such as service, operation name, tags and duration. Some interesting data will be summarized for you, such as the percentage of time spent in a service, and whether or not operations failed.
Application's need to be “instrumented” to report trace data to Zipkin. This usually means configuration of a tracer or instrumentation library. The most popular ways to report data to Zipkin are via github.com/openzipkin/zipkin 中下载 zipkin.jar
java -jar zipkin.jar
版本说明
项目结构
项目采用父工程集成多模块的方式构建而成,demo-zipkin 父工程聚合了zipkin-1、zipkin-2、zipkin-3、zipkin-4、zipkin-5 五个 Module。
demo-zipkin zipkin-1 |-SpanCollectorConfig |-application.properties |-ZipkinController |-Application1 zipkin-2 |-SpanCollectorConfig |-application.properties |-ZipkinController2 |-Application1 zipkin-3 |-SpanCollectorConfig |-application.properties |-ZipkinController3 |-Application1 zipkin-4 |-SpanCollectorConfig |-application.properties |-ZipkinController4 |-Application1 zipkin-5 |-SpanCollectorConfig |-application.properties |-ZipkinController5 |-Application1
工程端口分配
每个 Module 使用不同的端口,分别启动自己的Application。
引入 Maven 依赖
<properties> <zipkin.version>3.9.0</zipkin.version> </properties> <!-- Springboot 相关 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- zipkin相关 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-core</artifactId> <version>${zipkin.version}</version> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-spancollector-localhost:9411 zipkin.connectTimeout=6000 zipkin.readTimeout=6000 zipkin.flushInterval=1 zipkin.compressionEnabled=true zipkin.samplerRate=1 server.port=8081 server.servlet.context-path=/
配置Span收集器
设置收集器的详细参数,包含超时时间、上传span间隔、以及配置采集率等,进而对收集器进行初始化。
package com.anqi.zipkin.bean; 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.localhost:8082/zipkin/service2"; @Autowired OkHttpClient client; @GetMapping("/service1") public String service() { Request request = new Request.Builder().url(url).build(); Response response; try { response = client.newCall(request).execute(); return response.body().string(); } catch (Exception e) { e.printStackTrace(); } return "null"; } }
Zipkin-2中的Controller
package com.anqi.zipkin.controller; import oklocalhost:8083/zipkin/service3"; public static final String url2 = "localhost:8084/zipkin/service4"; @Autowired OkHttpClient client; @GetMapping("/service2") public String service() throws Exception { System.out.println("loading-----"); 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 "con2 + "+ response1.body().string() + "-" + response2.body().string(); } }
Zipkin-3中的Controller
package com.anqi.zipkin.controller; import oklocalhost:8084/zipkin/service4"; @Autowired OkHttpClient client; @GetMapping("/service3") public String service() throws Exception { Request request = new Request.Builder().url(url).build(); Response response = client.newCall(request).execute(); return "con3 + "+ response.body().string(); } }
Zipkin-4中的Controller
package com.anqi.zipkin.controller; import oklocalhost:8085/zipkin/service5"; @Autowired OkHttpClient client; @GetMapping("/service4") public String service() throws Exception { Request request = new Request.Builder().url(url).build(); Response response = client.newCall(request).execute(); return "con4 + "+ response.body().string(); } }
Zipkin-5中的Controller
package com.anqi.zipkin.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("zipkin") public class ZipkinController5 { @GetMapping("/service5") public String service() throws Exception { return "service5 -----"; } }
Springboot 启动类
package com.anqi.zipkin; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application1 { public static void main(String[] args) { SpringApplication.run(Application1.class); } }
运行分析
在地址栏请求urllocalhost:8081/zipkin/service1,然后访问localhost:9411/zipkin/
查看服务调用耗时
查看服务依赖关系
核心概念
通过上图可以了解到共有7个span,分别为
{ "zipkin-1":["Server Start", "Server Finish"], "myzipkin-1,myzipkin-2": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-2,myzipkin-3": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-3,myzipkin-4": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-4,myzipkin-5": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-2,myzipkin-4": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-4,myzipkin-5": ["Client Start", "Server Start", "Client Finish", "Server Finish"], }
在json文件中选取两个子集进行分析
基本数据:用于跟踪树中节点的关联和界面展示,包括traceId、spanId、parentId、name、timestamp和duration,其中parentId为null的Span将成为跟踪树的根节点来展示,当然它也是调用链的起点,为了节省一次spanId的创建开销,让顶级Span变得更明显,顶级Span中spanId将会和traceId相同。timestamp用于记录调用的起始时间,而duration表示此次调用的总耗时,所以timestamp+duration将表示成调用的结束时间,而duration在跟踪树中将表示成该Span的时间条的长度。需要注意的是,这里的name用于在跟踪树节点的时间条上展示。traceId:标记一次请求的跟踪,相关的Spans都有相同的traceId。kind :zipkin最新V2版本的API中,不再要求在annotations中上传cs,cr,sr,ss。而是通过kind标记是server-side span还是client-side span,两端记录自己的timestap来取代cs和sr,记录duration来取代cr和ss
{ "traceId": "867a9e3867736b17", "parentId": "96f19423db38c90d", "id": "6c9fd521b6589b7f", "kind": "SERVER", "name": "get", "timestamp": 1568103422569000, "duration": 6000, "localEndpoint": { "serviceName": "myzipkin-4", "ipv4": "192.168.1.160" }, "tags": { "localhost:8082/zipkin/service2" } }
总结
以上所述是小编给大家介绍的SpringBoot集成Zipkin实现分布式全链路监控,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对自由互联网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
本文共计2890个文字,预计阅读时间需要12分钟。
Zipkin简介:Zipkin是一个分布式追踪系统。它协助收集分析服务架构中处理延迟所需的时间数据。功能包括数据的收集和查询。若你拥有一个低级别的跟踪ID,可直接在Zipkin中查询。
Zipkin 简介
Zipkin is a distributed tracing system. It helps gather timing data needed to troubleshoot latency problems in service architectures. Features include both the collection and lookup of this data.
If you have a trace ID in a log file, you can jump directly to it. Otherwise, you can query based on attributes such as service, operation name, tags and duration. Some interesting data will be summarized for you, such as the percentage of time spent in a service, and whether or not operations failed.
Application's need to be “instrumented” to report trace data to Zipkin. This usually means configuration of a tracer or instrumentation library. The most popular ways to report data to Zipkin are via github.com/openzipkin/zipkin 中下载 zipkin.jar
java -jar zipkin.jar
版本说明
项目结构
项目采用父工程集成多模块的方式构建而成,demo-zipkin 父工程聚合了zipkin-1、zipkin-2、zipkin-3、zipkin-4、zipkin-5 五个 Module。
demo-zipkin zipkin-1 |-SpanCollectorConfig |-application.properties |-ZipkinController |-Application1 zipkin-2 |-SpanCollectorConfig |-application.properties |-ZipkinController2 |-Application1 zipkin-3 |-SpanCollectorConfig |-application.properties |-ZipkinController3 |-Application1 zipkin-4 |-SpanCollectorConfig |-application.properties |-ZipkinController4 |-Application1 zipkin-5 |-SpanCollectorConfig |-application.properties |-ZipkinController5 |-Application1
工程端口分配
每个 Module 使用不同的端口,分别启动自己的Application。
引入 Maven 依赖
<properties> <zipkin.version>3.9.0</zipkin.version> </properties> <!-- Springboot 相关 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- zipkin相关 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-core</artifactId> <version>${zipkin.version}</version> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-spancollector-localhost:9411 zipkin.connectTimeout=6000 zipkin.readTimeout=6000 zipkin.flushInterval=1 zipkin.compressionEnabled=true zipkin.samplerRate=1 server.port=8081 server.servlet.context-path=/
配置Span收集器
设置收集器的详细参数,包含超时时间、上传span间隔、以及配置采集率等,进而对收集器进行初始化。
package com.anqi.zipkin.bean; 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.localhost:8082/zipkin/service2"; @Autowired OkHttpClient client; @GetMapping("/service1") public String service() { Request request = new Request.Builder().url(url).build(); Response response; try { response = client.newCall(request).execute(); return response.body().string(); } catch (Exception e) { e.printStackTrace(); } return "null"; } }
Zipkin-2中的Controller
package com.anqi.zipkin.controller; import oklocalhost:8083/zipkin/service3"; public static final String url2 = "localhost:8084/zipkin/service4"; @Autowired OkHttpClient client; @GetMapping("/service2") public String service() throws Exception { System.out.println("loading-----"); 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 "con2 + "+ response1.body().string() + "-" + response2.body().string(); } }
Zipkin-3中的Controller
package com.anqi.zipkin.controller; import oklocalhost:8084/zipkin/service4"; @Autowired OkHttpClient client; @GetMapping("/service3") public String service() throws Exception { Request request = new Request.Builder().url(url).build(); Response response = client.newCall(request).execute(); return "con3 + "+ response.body().string(); } }
Zipkin-4中的Controller
package com.anqi.zipkin.controller; import oklocalhost:8085/zipkin/service5"; @Autowired OkHttpClient client; @GetMapping("/service4") public String service() throws Exception { Request request = new Request.Builder().url(url).build(); Response response = client.newCall(request).execute(); return "con4 + "+ response.body().string(); } }
Zipkin-5中的Controller
package com.anqi.zipkin.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("zipkin") public class ZipkinController5 { @GetMapping("/service5") public String service() throws Exception { return "service5 -----"; } }
Springboot 启动类
package com.anqi.zipkin; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application1 { public static void main(String[] args) { SpringApplication.run(Application1.class); } }
运行分析
在地址栏请求urllocalhost:8081/zipkin/service1,然后访问localhost:9411/zipkin/
查看服务调用耗时
查看服务依赖关系
核心概念
通过上图可以了解到共有7个span,分别为
{ "zipkin-1":["Server Start", "Server Finish"], "myzipkin-1,myzipkin-2": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-2,myzipkin-3": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-3,myzipkin-4": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-4,myzipkin-5": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-2,myzipkin-4": ["Client Start", "Server Start", "Client Finish", "Server Finish"], "myzipkin-4,myzipkin-5": ["Client Start", "Server Start", "Client Finish", "Server Finish"], }
在json文件中选取两个子集进行分析
基本数据:用于跟踪树中节点的关联和界面展示,包括traceId、spanId、parentId、name、timestamp和duration,其中parentId为null的Span将成为跟踪树的根节点来展示,当然它也是调用链的起点,为了节省一次spanId的创建开销,让顶级Span变得更明显,顶级Span中spanId将会和traceId相同。timestamp用于记录调用的起始时间,而duration表示此次调用的总耗时,所以timestamp+duration将表示成调用的结束时间,而duration在跟踪树中将表示成该Span的时间条的长度。需要注意的是,这里的name用于在跟踪树节点的时间条上展示。traceId:标记一次请求的跟踪,相关的Spans都有相同的traceId。kind :zipkin最新V2版本的API中,不再要求在annotations中上传cs,cr,sr,ss。而是通过kind标记是server-side span还是client-side span,两端记录自己的timestap来取代cs和sr,记录duration来取代cr和ss
{ "traceId": "867a9e3867736b17", "parentId": "96f19423db38c90d", "id": "6c9fd521b6589b7f", "kind": "SERVER", "name": "get", "timestamp": 1568103422569000, "duration": 6000, "localEndpoint": { "serviceName": "myzipkin-4", "ipv4": "192.168.1.160" }, "tags": { "localhost:8082/zipkin/service2" } }
总结
以上所述是小编给大家介绍的SpringBoot集成Zipkin实现分布式全链路监控,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对自由互联网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

