您的位置:首页 > 编程语言 > Java开发

zipkin简单介绍及环境搭建(一)

2017-04-21 00:00 363 查看

什么是zipkin

Zipkin 是 Twitter 的一个开源项目,允许开发者收集 Twitter 各个服务上的监控数据,并提供查询接口

为什么要使用zipkin

随着业务发展,系统拆分导致系统调用链路愈发复杂一个前端请求可能最终需要调用很多次后端服务才能完成,当整个请求变慢或不可用时,我们是无法得知该请求是由某个或某些后端服务引起的,这时就需要解决如何快读定位服务故障点,以对症下药。于是就有了分布式系统调用跟踪的诞生。而zipkin就是开源分布式系统调用跟踪的佼佼者

zipkin基于google-Dapper的论文有兴趣的可以看下

google-Dapper

zipkin体系介绍

zipkin架构



包含组件

controller 控制器

storage 存储

api 查询api

ui 界面

zipkin存储

zipkin存储默认使用inMemory

支持存储模式

inMemory

mysql

Cassandra

Elasticsearch

ZipKin数据模型

Trace:一组代表一次用户请求所包含的spans,其中根span只有一个。

Span: 一组代表一次HTTP/RPC请求所包含的annotations。

annotation:包括一个值,时间戳,主机名(留痕迹)。

几个时间

cs:客户端发起请求,标志Span的开始

sr:服务端接收到请求,并开始处理内部事务,其中sr - cs则为网络延迟和时钟抖动

ss:服务端处理完请求,返回响应内容,其中ss - sr则为服务端处理请求耗时

cr:客户端接收到服务端响应内容,标志着Span的结束,其中cr - ss则为网络延迟和时钟抖动

搭建zipkin

下载文件

zipkin last jar 下载地址

zipkin-github

启动zipkin

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

使用elasticsearch-5.3.0作为存储启动zipkin

链接

elasticsearch-5.3.0下载

github
解压elasticsearch-5.3.0运行



启动完成界面



启动zipkin使用elasticsearch

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 依赖

springboot+apache-httpclient使用zipkin

项目结构



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);
/*
* 1、执行execute()的前后,会执行相应的拦截器(cs,cr)
* 2、请求在被调用方执行的前后,也会执行相应的拦截器(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);
/*
* 1、执行execute()的前后,会执行相应的拦截器(cs,cr)
* 2、请求在被调用方执行的前后,也会执行相应的拦截器(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)

参考

分布式系统调用跟踪实践

Brave接入ZipKin实现调用链跟踪【上】

Architecture
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息