一、总体信息
代码位置:https://gitee.com/DanShenGuiZu/learnDemo/tree/master/zipkin-learn
1.1、端口配置
服务名称 | 端口 |
---|---|
service8081 | 8081 |
service8082 | 8082 |
service8083 | 8083 |
service8084 | 8084 |
service8085 | 8085 |
二、搭建service8081
2.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.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>fei.zhou</groupId>
<artifactId>service8081</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service8081</name>
<properties>
<java.version>1.8</java.version>
<zipkin.version>3.9.0</zipkin.version>
</properties>
<dependencies>
<!-- Springboot 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
</project>
```
## 2.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=1
server.port=8081
server.servlet.context-path=/
spring.application.name=service8081
```
## 2.3、Span收集器配置
```
package fei.zhou.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间隔、以及配置采集率等,进而对收集器进行初始化。
*
* @author <a href="mailto:zhoufei@smartdot.com">周飞</a>
* @since 2021/8/22 15:47
*/
@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
*/
@Bean
public 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
*/
@Bean
public 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: 过滤器
*/
@Bean
public BraveServletFilter braveServletFilter(Brave brave) {
BraveServletFilter filter = new BraveServletFilter(brave.serverRequestInterceptor(),
brave.serverResponseInterceptor(), new DefaultSpanNameProvider());
return filter;
}
/**
* @Description: 设置client的 rs(表示服务端收到请求)和cs(表示客户端发起请求)的拦截器
* @Param:
* @return: OkHttpClient 返回请求实例
*/
@Bean
public OkHttpClient okHttpClient(Brave brave) {
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new BraveOkHttpRequestResponseInterceptor(brave.clientRequestInterceptor(),
brave.clientResponseInterceptor(), new DefaultSpanNameProvider()))
.build();
return httpClient;
}
}
```
## 2.4、HelloController
```
/**
* 所属项目:北京慧点科技有限公司XCOA产品。
* 注意:本内容仅限于内部传阅,禁止外泄以及用于其他的商业目的。
*
* @Date: 2021/8/22
* @Copyright: Copyright 2020 © Smartdot Technologies Co., Ltd.
*/
package fei.zhou.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
* @date 2021/8/22 15:54
* @author <a href="mailto:zhoufei@smartdot.com">周飞</a>
* @Verson 1.0 -2021/8/22 15:54
* @see
*/
@RestController
@RequestMapping("zipkin")
public class HelloController {
public static final String url = "http://localhost:8082/zipkin/service2";
@Autowired
OkHttpClient 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的配置
## 3.1、application.properties 修改
```
zipkin.serviceName= 改为自己的服务名称
server.port=改为自己的端口
spring.application.name=改为自己的服务名称
```
## 3.2、HelloController 修改
#### service8081
```
@RestController
@RequestMapping("zipkin")
public class HelloController {
public static final String url = "http://localhost:8082/zipkin/service2";
@Autowired
OkHttpClient 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
```
@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";
@Autowired
OkHttpClient 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() + "】";
}
}
```
#### service8083
```
@RestController
@RequestMapping("zipkin")
public class HelloController {
public static final String url = "http://localhost:8084/zipkin/service4";
@Autowired
OkHttpClient 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();
}
}
```
#### service8084
```
@RestController
@RequestMapping("zipkin")
public class HelloController {
public static final String url = "http://localhost:8085/zipkin/service5";
@Autowired
OkHttpClient 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();
}
}
```
#### service8085
```
@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/service1
http://localhost:9411
```
## 4.1、发送请求
![在这里插入图片描述](https://img-blog.csdnimg.cn/d060e5e0347e4a1a9bebb22e7dfba7af.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3U5MjA3ODYzMTI=,size_16,color_FFFFFF,t_70#pic_center)
## 4.2、分析
#### spans分析
![在这里插入图片描述](https://img-blog.csdnimg.cn/d17843c6ad7945fa89d19ff76ee5cf8f.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3U5MjA3ODYzMTI=,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/86984d71f4b444a5bd8c636ce3ddc5e0.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3U5MjA3ODYzMTI=,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/3ff20d5cb47249669ef80e4ac413bf18.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3U5MjA3ODYzMTI=,size_16,color_FFFFFF,t_70#pic_center)
#### json样例数据
```
[
{
"traceId": "5281f0926d831233",
"parentId": "c5e07bd06c63cc0e",
"id": "cb2631a28d96bac7",
"kind": "SERVER",
"name": "get",
"timestamp": 1629624228145000,
"duration": 3000,
"localEndpoint": {
"serviceName": "service8085",
"ipv4": "192.168.2.12"
},
"tags": {
"http.status_code": "200",
"http.url": "/zipkin/service5"
}
},
{
"traceId": "5281f0926d831233",
"parentId": "a5d0b5028b7020c5",
"id": "c5e07bd06c63cc0e",
"kind": "CLIENT",
"name": "get",
"timestamp": 1629624228133000,
"duration": 17000,
"localEndpoint": {
"serviceName": "service8083",
"ipv4": "192.168.2.12"
},
"tags": {
"http.url": "http://localhost:8084/zipkin/service4"
}
},
{
"traceId": "5281f0926d831233",
"parentId": "5a152eade3bc5bec",
"id": "a5d0b5028b7020c5",
"kind": "SERVER",
"name": "get",
"timestamp": 1629624228132000,
"duration": 20000,
"localEndpoint": {
"serviceName": "service8083",
"ipv4": "192.168.2.12"
},
"tags": {
"http.status_code": "200",
"http.url": "/zipkin/service3"
}
},
{
"traceId": "5281f0926d831233",
"parentId": "5281f0926d831233",
"id": "5a152eade3bc5bec",
"kind": "CLIENT",
"name": "get",
"timestamp": 1629624228120000,
"duration": 46000,
"localEndpoint": {
"serviceName": "service8081",
"ipv4": "192.168.2.12"
},
"tags": {
"http.url": "http://localhost:8082/zipkin/service2"
}
},
{
"traceId": "5281f0926d831233",
"id": "5281f0926d831233",
"kind": "SERVER",
"name": "get",
"timestamp": 1629624228118000,
"duration": 50000,
"localEndpoint": {
"serviceName": "service8081",
"ipv4": "192.168.2.12"
},
"tags": {
"http.status_code": "200",
"http.url": "/zipkin/service1"
}
}
]
```
#### 服务依赖关系
![在这里插入图片描述](https://img-blog.csdnimg.cn/bf49a714f6fe4fd48a6dd877a41fbb9e.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3U5MjA3ODYzMTI=,size_16,color_FFFFFF,t_70#pic_center)