2018-08-30 14:40:07.0|分类: docker+node.js+zookeeper构建微服务|浏览量: 1476
docker镜像官网 https://hub.docker.com/u/library/ zipkin镜像版本列表 https://hub.docker.com/r/openzipkin/zipkin/tags/ 随着业务越来越复杂,系统也随之进行各种拆分,特别是随着微服务架构和容器技术的兴起,看似简单的一个应用,后台可能有几十个甚至几百个服务在支撑;一个前端的请求可能需要多次的服务调用最后才能完成;当请求变慢或者不可用时,我们无法得知是哪个后台服务引起的,这时就需要解决如何快速定位服务故障点,Zipkin分布式跟踪系统就能很好的解决这样的问题。 跟踪器(Tracers)存在在你的应用程序中生存,记录时间和关于操作的元数据。他们经常使用库,因此他们的使用对用户是透明的。例如,当它收到一个请求并发送一个响应时,一个感应器(instrumented )的web服务器记录。所收集的跟踪数据称为Span。 zipkin重要概念: Span:基本工作单元,一次链路调用(可以是RPC,DB等没有特定的限制)创建一个span,通过一个64位ID标识它, span通过还有其他的数据,例如描述信息,时间戳,key-value对的(Annotation)tag信息,parent-id等,其中parent-id 可以表示span调用链路来源,通俗的理解span就是一次请求信息 Trace:类似于树结构的Span集合,表示一条调用链路,存在唯一标识 Annotation: 注解,用来记录请求特定事件相关信息(例如时间),通常包含四个注解信息 官网提供例子流程图: ┌─────────────┐ ┌───────────────────────┐ ┌─────────────┐ ┌──────────────────┐ │ User Code │ │ Trace Instrumentation │ │ Http Client │ │ Zipkin Collector │ └─────────────┘ └───────────────────────┘ └─────────────┘ └──────────────────┘ │ │ │ │ ┌─────────┐ │ ──┤GET /foo ├─▶ │ ────┐ │ │ └─────────┘ │ record tags │ │ ◀───┘ │ │ ────┐ │ │ │ add trace headers │ │ ◀───┘ │ │ ────┐ │ │ │ record timestamp │ │ ◀───┘ │ │ ┌─────────────────┐ │ │ ──┤GET /foo ├─▶ │ │ │X-B3-TraceId: aa │ ────┐ │ │ │X-B3-SpanId: 6b │ │ │ │ └─────────────────┘ │ invoke │ │ │ │ request │ │ │ │ │ │ │ ┌────────┐ ◀───┘ │ │ ◀─────┤200 OK ├─────── │ │ ────┐ └────────┘ │ │ │ record duration │ │ ┌────────┐ ◀───┘ │ ◀──┤200 OK ├── │ │ │ └────────┘ ┌────────────────────────────────┐ │ │ ──┤ asynchronously report span ├────▶ │ │ │ │{ │ │ "traceId": "aa", │ │ "id": "6b", │ │ "name": "get", │ │ "timestamp": 1483945573944000,│ │ "duration": 386000, │ │ "annotations": [ │ │--snip-- │ └────────────────────────────────┘ docker安装zipkin docker run -d -p 9411:9411 --name zipkin openzipkin/zipkin1.22.0 用springboot构建一个例子,例子访问流程图如下: business/order/user服务程序,代码非常相似。zipkin-conca是zipkin基础代码,business/order/user都需要引用zipkin-conca。 business项目内容: App.java package com.cookqq.business; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; /** * Hello world! * */ @SpringBootApplication(scanBasePackages="com.cookqq") public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } } BusinessController.java package com.cookqq.business; import java.util.Random; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class BusinessController { @Autowired private RestTemplate restTemplate; @RequestMapping( method=RequestMethod.GET, path="/show") public String show(){ try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } return restTemplate.getForObject("http://127.0.0.1:8081/order", String.class); } } application.properties server.port=8080 zipkin.endpoint=http://192.168.99.100:9411/api/v1/spans zipkin.service=business 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.cookqq</groupId> <artifactId>business</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>business</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <repositories> <repository> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> </repository> <repository> <id>jcenter</id> <name>jcenter Repository</name> <url>http://jcenter.bintray.com/</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.cookqq</groupId> <artifactId>zipkin-conca</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project> zipkin-conca项目 ZipkinConfiguration类 package com.cookqq.zipkin.conca; import com.github.kristofa.brave.Brave; import com.github.kristofa.brave.http.HttpRequest; import com.github.kristofa.brave.http.SpanNameProvider; import com.github.kristofa.brave.mysql.MySQLStatementInterceptorManagementBean; import com.github.kristofa.brave.spring.BraveClientHttpRequestInterceptor; import com.github.kristofa.brave.spring.ServletHandlerInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.web.client.RestTemplate; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import zipkin.Span; import zipkin.reporter.AsyncReporter; import zipkin.reporter.Reporter; import zipkin.reporter.Sender; import zipkin.reporter.okhttp3.OkHttpSender; import javax.annotation.PostConstruct; import java.util.List; @Configuration @Import({RestTemplate.class, BraveClientHttpRequestInterceptor.class, ServletHandlerInterceptor.class}) public class ZipkinConfiguration extends WebMvcConfigurerAdapter { @Autowired private ZipkinProperties zipkinProperties; @Bean public Sender sender() { return OkHttpSender.create(zipkinProperties.getEndpoint()); } @Bean public Reporter<Span> reporter() { // return new LoggingReporter(); return AsyncReporter.builder(sender()).build(); } @Bean public Brave brave() { return new Brave.Builder(zipkinProperties.getService()).reporter(reporter()).build(); } @Bean public SpanNameProvider spanNameProvider() { // return new DefaultSpanNameProvider(); return new SpanNameProvider() { public String spanName(HttpRequest httpRequest) { return String.format( "%s %s", httpRequest.getHttpMethod(), httpRequest.getUri().getPath() ); } }; } // @Bean // public MySQLStatementInterceptorManagementBean mySQLStatementInterceptorManagementBean() { // return new MySQLStatementInterceptorManagementBean(brave().clientTracer()); // } @Autowired private RestTemplate restTemplate; @Autowired private BraveClientHttpRequestInterceptor clientInterceptor; @Autowired private ServletHandlerInterceptor serverInterceptor; @PostConstruct public void init() { List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors(); interceptors.add(clientInterceptor); restTemplate.setInterceptors(interceptors); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(serverInterceptor); } } ZipkinProperties类 package com.cookqq.zipkin.conca; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties("zipkin") public class ZipkinProperties { private String endpoint; private String service; public String getEndpoint() { return endpoint; } public void setEndpoint(String endpoint) { this.endpoint = endpoint; } public String getService() { return service; } public void setService(String service) { this.service = service; } } 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.cookqq</groupId> <artifactId>zipkin-conca</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>zipkin-conca</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot</artifactId> <version>1.5.2.RELEASE</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.7.RELEASE</version> <scope>provided</scope> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-spring-web-servlet-interceptor</artifactId> <version>4.0.6</version> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-spring-resttemplate-interceptors</artifactId> <version>4.0.6</version> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-mysql</artifactId> <version>4.0.6</version> </dependency> <dependency> <groupId>io.zipkin.reporter</groupId> <artifactId>zipkin-sender-okhttp3</artifactId> <version>0.6.12</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project> 启动三个项目,访问http://localhost:8080/show 上述代码测试过zipkin版本1.22.0,2.6.0,2.8.0(支持), 2.10.0(不支持) |