zipkin簡單介紹及環境搭建(一)

什麼是zipkin

Zipkin 是 Twitter 的一個開源項目,容許開發者收集 Twitter 各個服務上的監控數據,並提供查詢接口html

爲何要使用zipkin

隨着業務發展,系統拆分致使系統調用鏈路愈發複雜一個前端請求可能最終須要調用不少次後端服務才能完成,當整個請求變慢或不可用時,咱們是沒法得知該請求是由某個或某些後端服務引發的,這時就須要解決如何快讀定位服務故障點,以對症下藥。因而就有了分佈式系統調用跟蹤的誕生。而zipkin就是開源分佈式系統調用跟蹤的佼佼者前端

zipkin基於google-Dapper的論文有興趣的能夠看下java

google-Dappermysql

zipkin體系介紹

zipkin架構

image 包含組件git

  • controller 控制器
  • storage 存儲
  • api 查詢api
  • ui 界面

zipkin存儲

zipkin存儲默認使用inMemorygithub

支持存儲模式web

  • inMemory
  • mysql
  • Cassandra
  • Elasticsearch

ZipKin數據模型

  • Trace:一組表明一次用戶請求所包含的spans,其中根span只有一個。
  • Span: 一組表明一次HTTP/RPC請求所包含的annotations。
  • annotation:包括一個值,時間戳,主機名(留痕跡)。

幾個時間spring

  • cs:客戶端發起請求,標誌Span的開始
  • sr:服務端接收到請求,並開始處理內部事務,其中sr - cs則爲網絡延遲和時鐘抖動
  • ss:服務端處理完請求,返回響應內容,其中ss - sr則爲服務端處理請求耗時
  • cr:客戶端接收到服務端響應內容,標誌着Span的結束,其中cr - ss則爲網絡延遲和時鐘抖動

搭建zipkin

下載文件

啓動zipkin

java -jar zipkin-server-1.22.1-exec.jarsql

使用elasticsearch-5.3.0做爲存儲啓動zipkin

連接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 控制檯 image zipkin 明細 image zipkin 依賴

springboot+apache-httpclient使用zipkin

項目結構

image

pom.xml
<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";
    }
}

關注點point

  • zipkin 運行須要jdk8
  • pinpoint 能夠關注下,一樣是分佈式鏈路追蹤系統(ps:搭建環境1天下來,trace一直不能生成。。有誰碰到過這個問題能夠回覆下 0.0)

參考

相關文章
相關標籤/搜索