Zipkin 是 Twitter 的一個開源項目,容許開發者收集 Twitter 各個服務上的監控數據,並提供查詢接口html
隨着業務發展,系統拆分致使系統調用鏈路愈發複雜一個前端請求可能最終須要調用不少次後端服務才能完成,當整個請求變慢或不可用時,咱們是沒法得知該請求是由某個或某些後端服務引發的,這時就須要解決如何快讀定位服務故障點,以對症下藥。因而就有了分佈式系統調用跟蹤的誕生。而zipkin就是開源分佈式系統調用跟蹤的佼佼者前端
zipkin基於google-Dapper的論文有興趣的能夠看下java
google-Dappermysql
包含組件git
zipkin存儲默認使用inMemorygithub
支持存儲模式web
幾個時間spring
java -jar zipkin-server-1.22.1-exec.jarsql
連接apache
java -jar zipkin-server-1.22.1-exec.jar --STORAGE_TYPE=elasticsearch --DES_HOSTS=http://localhost:9200 zipkin-server-1.22.1-exec.jar採用springboot編寫,springboot傳入參數使用--key=value. 當前爲何使用--STORAGE_TYPE,--DES_HOSTS由配置文件裏面決定
zipkin 控制檯 zipkin 明細 zipkin 依賴
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.kite.zipkin</groupId> <artifactId>zipkin-demo-server</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>zipkin-demo-server</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- brave core --> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-core</artifactId> <version>3.9.0</version> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-spancollector-http</artifactId> <version>3.9.0</version> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-web-servlet-filter</artifactId> <version>3.9.0</version> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-apache-http-interceptors</artifactId> <version>3.9.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
ZipkinConfig
package com.kite.zipkin.config; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.httpclient.BraveHttpRequestInterceptor; import com.github.kristofa.brave.httpclient.BraveHttpResponseInterceptor; import com.github.kristofa.brave.servlet.BraveServletFilter; @Configuration public class ZipkinConfig { //span(一次請求信息或者一次鏈路調用)信息收集器 @Bean public SpanCollector spanCollector() { Config config = HttpSpanCollector.Config.builder() .compressionEnabled(false)// 默認false,span在transport以前是否會被gzipped .connectTimeout(5000) .flushInterval(1) .readTimeout(6000) .build(); return HttpSpanCollector.create("http://localhost:9411", config, new EmptySpanCollectorMetricsHandler()); } //做爲各調用鏈路,只須要負責將指定格式的數據發送給zipkin @Bean public Brave brave(SpanCollector spanCollector){ Builder builder = new Builder("service1");//指定serviceName builder.spanCollector(spanCollector); builder.traceSampler(Sampler.create(1));//採集率 return builder.build(); } //設置server的(服務端收到請求和服務端完成處理,並將結果發送給客戶端)過濾器 @Bean public BraveServletFilter braveServletFilter(Brave brave) { BraveServletFilter filter = new BraveServletFilter(brave.serverRequestInterceptor(), brave.serverResponseInterceptor(), new DefaultSpanNameProvider()); return filter; } //設置client的(發起請求和獲取到服務端返回信息)攔截器 @Bean public CloseableHttpClient okHttpClient(Brave brave){ CloseableHttpClient httpclient = HttpClients.custom() .addInterceptorFirst(new BraveHttpRequestInterceptor(brave.clientRequestInterceptor(), new DefaultSpanNameProvider())) .addInterceptorFirst(new BraveHttpResponseInterceptor(brave.clientResponseInterceptor())) .build(); return httpclient; } }
ZipkinBraveController
package com.kite.zipkin.controller; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ZipkinBraveController { @Autowired private CloseableHttpClient okHttpClient; @GetMapping("/service1") public String myboot() throws Exception { Thread.sleep(100);//100ms HttpGet get = new HttpGet("http://localhost:81/test"); CloseableHttpResponse execute = okHttpClient.execute(get); /* * 一、執行execute()的先後,會執行相應的攔截器(cs,cr) * 二、請求在被調用方執行的先後,也會執行相應的攔截器(sr,ss) */ return EntityUtils.toString(execute.getEntity(), "utf-8"); } }
Application啓動類
package com.kite.zipkin; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
======================
zipkin-demo-server-2 serviceName修改
public Brave brave(SpanCollector spanCollector){ Builder builder = new Builder("service2");//指定serviceName builder.spanCollector(spanCollector); builder.traceSampler(Sampler.create(1));//採集率 return builder.build(); }
controller修改
package com.kite.zipkin.controller; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ZipkinBraveController { @Autowired private CloseableHttpClient httpClient; @GetMapping("/test") public String myboot() throws Exception { Thread.sleep(200);//100ms HttpGet get1 = new HttpGet("http://localhost:82/test"); CloseableHttpResponse execute1 = httpClient.execute(get1); /* * 一、執行execute()的先後,會執行相應的攔截器(cs,cr) * 二、請求在被調用方執行的先後,也會執行相應的攔截器(sr,ss) */ HttpGet get2 = new HttpGet("http://localhost:83/test"); CloseableHttpResponse execute2 = httpClient.execute(get2); return EntityUtils.toString(execute1.getEntity(), "utf-8") + "-" +EntityUtils.toString(execute2.getEntity(), "utf-8"); } }
zipkin-demo-server-3 serviceName修改
@Bean public Brave brave(SpanCollector spanCollector){ Builder builder = new Builder("service3");//指定serviceName builder.spanCollector(spanCollector); builder.traceSampler(Sampler.create(1));//採集率 return builder.build(); }
controller修改
package com.kite.zipkin.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ZipkinBraveController { @GetMapping("/test") public String myboot() throws Exception { Thread.sleep(100);//100ms return "service3"; } }
zipkin-demo-server-4 serviceName修改
@Bean public Brave brave(SpanCollector spanCollector){ Builder builder = new Builder("service4");//指定serviceName builder.spanCollector(spanCollector); builder.traceSampler(Sampler.create(1));//採集率 return builder.build(); }
controller修改
package com.kite.zipkin.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ZipkinBraveController { @GetMapping("/test") public String myboot() throws Exception { Thread.sleep(100);//100ms return "service3"; } }