Zipkin存储Sleuth信息实现调用链追踪的几种方法
发布日期:2021-06-20 07:26:34 浏览次数:22 分类:技术文章

本文共 81765 字,大约阅读时间需要 272 分钟。

转载自,原文格式清晰:

一、基本概念

大家知道,对于分布式应用系统,特别是微服务应用,服务之间的调用链跟踪是极其重要的。在Springcloud的微服务框架中提供了Springcloud Sleuth结合Zipkin的调用链跟踪方案,其理论基础主要来自于 Google 的一篇论文

Spring Cloud Sleuth为服务之间调用提供链路追踪。通过Sleuth可以很清楚的了解到一个服务请求经过了哪些服务,每个服务处理花费了多长。从而让我们可以很方便的理清各微服务间的调用关系。

Sleuth还可以帮助我们进行:

  • 耗时分析: 通过Sleuth可以很方便的了解到每个采样请求的耗时,从而分析出哪些服务调用比较耗时;
  • 可视化错误: 对于程序未捕捉的异常,可以通过集成Zipkin服务界面上看到;
  • 链路优化: 对于调用比较频繁的服务,可以针对这些服务实施一些优化措施。

 

而zipkin可以收集Sleuth的采样数据,利用zipkin的存储来存储信息,利用zipkin ui来展示数据。根据其官方文档,其架构如下,

其中四个组件的作用如下

Zipkin Collector

Once the trace data arrives at the Zipkin collector daemon, it is validated, stored, and indexed for lookups by the Zipkin collector.

Storage

Zipkin was initially built to store data on Cassandra since Cassandra is scalable, has a flexible schema, and is heavily used within Twitter. However, we made this component pluggable. In addition to Cassandra, we natively support ElasticSearch and MySQL. Other back-ends might be offered as third party extensions.

Zipkin Query Service

Once the data is stored and indexed, we need a way to extract it. The query daemon provides a simple JSON API for finding and retrieving traces. The primary consumer of this API is the Web UI.

Web UI

We created a GUI that presents a nice interface for viewing traces. The web UI provides a method for viewing traces based on service, time, and annotations. Note: there is no built-in authentication in the UI!

其中最重要的collector的工作原理如下

───────┐ ┌───────────────────────┐  ┌─────────────┐  ┌──────────────────┐    
│ 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-- │
└────────────────────────────────┘

本文通过示例来介绍Zipkin存储和展示Sleuth数据的几种方式

二、示例环境介绍

在搭建zipkin server前,我们先写了以下几个服务

1,SERVICE-HI

通过访问http://localhost:8081/hi?name=aaa和http://localhost:8082/hi?name=aaa

返回 hi aaa,i am from port:8081 和hi aaa,i am from port:8082

2,SERVICE-RIBBON

通过访问http://localhost:8010/ribbon?name=xuwh 来实现ribbon的load balance功能,依次调用SERVICE-HI 服务的8081和8082端口

3,SERVICE-FEIGN-HYSTRIX

通过访问http://localhost:8020/feign?name=xuwh来实现feign的load balance功能,依次调用SERVICE-HI 服务的8081和8082端口

4,SERVICE-ZUUL

通过访问http://localhost:8040/feign/feign?name=xuwh和http://localhost:8040/feign/feign?name=xuwh来实现Zuul的路由功能

服务之间的访问链路如下图

三、通过http调用直接在zipkin UI 上显示调用链的配置方法

该方法实际上就是Collector直接通过http的方式收集信息,Zipkin UI读取collector的信息,并展示,信息不落地到数据库。需要改造Zipkin Client(即被监控服务)的配置和Zipkin Server的配置。

1,Zipkin server服务

(1)zipkin-server服务源码

package jar;    
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import zipkin.server.EnableZipkinServer;
@SpringBootApplication
@EnableEurekaClient
@EnableZipkinServer
public
class ZipkinServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinServerApplication.class, args);
}
}

(2)配置application.yml

server:    
port:
9411
spring:
application:
name: zipkin-server
eureka:
client:
service-url:
defaultZone: http:
//localhost:8761/eureka/

(3)pom.xml 加依赖

4.0.0
com.svw
zipkin-server
0.0.1-SNAPSHOT
jar
zipkin-server
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.5.6.RELEASE
UTF-8
UTF-8
1.8
Dalston.SR3
org.springframework.cloud
spring-cloud-starter-eureka
io.zipkin.java
zipkin-server
io.zipkin.java
zipkin-autoconfigure-ui
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin

这里最重要的是引入zipkin-server依赖,以及zipkin-autoconfigure-ui依赖

io.zipkin.java
zipkin-server
io.zipkin.java
zipkin-autoconfigure-ui

2,要跟踪链路的服务的改造(4个服务都要改)

(1)改配置

以SERVICE-ZUUL 为例

server:    
port: 8040
spring:
application:
name: service-zuul
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
percentage: 1.0
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
zuul:
routes:
user-route1:
# 该配置方式中,user-route只是给路由一个名称,可以任意起名。
service-id: SERVICE-FEIGN-HYSTRIX
path: /feign/**
# service-id对应的路径
user-route2:
# 该配置方式中,user-route只是给路由一个名称,可以任意起名。
service-id: SERVICE-RIBBON
path: /ribbon/**
# service-id对应的路径
security:
basic:
enabled:
true
# 开启基于HTTP basic的认证
user:
name: xuwh
# 配置登录的账号是user
password: password123
# 配置登录的密码是password123

在application.yml中增加了这几行配置

zipkin:    
base-url: http:
//localhost:9411
sleuth:
sampler:
percentage:
1.0

(2)加依赖

在pom.xml中增加以下依赖

org.springframework.cloud
spring-cloud-starter-zipkin

3,启动各个服务,

4,并对各个服务进行web访问操作,在调试中发现,由于增加了系统采样,SERVICE-ZUUL在调用其他服务的时候,由于超时,而我们又没定义超时熔断服务,所以会调用不成功,console报错如下

com.netflix.zuul.exception.ZuulException: Forwarding      
error
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.handleException(RibbonRoutingFilter.java:
188) ~[spring-cloud-netflix-core
-1.3
.4.RELEASE.jar:
1.3
.4.RELEASE]
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.forward(RibbonRoutingFilter.java:
163) ~[spring-cloud-netflix-core
-1.3
.4.RELEASE.jar:
1.3
.4.RELEASE]
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.run(RibbonRoutingFilter.java:
111) ~[spring-cloud-netflix-core
-1.3
.4.RELEASE.jar:
1.3
.4.RELEASE]
at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:
112) ~[zuul-core
-1.3
.0.jar:
1.3
.0]
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:
193) ~[zuul-core
-1.3
.0.jar:
1.3
.0]
at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:
157) ~[zuul-core
-1.3
.0.jar:
1.3
.0]
at com.netflix.zuul.FilterProcessor.route(FilterProcessor.java:
118) ~[zuul-core
-1.3
.0.jar:
1.3
.0]
at com.netflix.zuul.ZuulRunner.route(ZuulRunner.java:
96) ~[zuul-core
-1.3
.0.jar:
1.3
.0]
at com.netflix.zuul.http.ZuulServlet.route(ZuulServlet.java:
116) ~[zuul-core
-1.3
.0.jar:
1.3
.0]
at com.netflix.zuul.http.ZuulServlet.service(ZuulServlet.java:
81) ~[zuul-core
-1.3
.0.jar:
1.3
.0]
at org.springframework.web.servlet.mvc.ServletWrappingController.handleRequestInternal(ServletWrappingController.java:
157) [spring-webmvc
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.cloud.netflix.zuul.web.ZuulController.handleRequest(ZuulController.java:
44) [spring-cloud-netflix-core
-1.3
.4.RELEASE.jar:
1.3
.4.RELEASE]
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:
50) [spring-webmvc
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:
967) [spring-webmvc
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:
901) [spring-webmvc
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:
970) [spring-webmvc
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:
861) [spring-webmvc
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:
635) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:
846) [spring-webmvc
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:
742) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
231) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.tomcat.websocket.
server.WsFilter.doFilter(WsFilter.java:
52) [tomcat-embed-websocket
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.boot.web.
filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:
55) [spring-boot
-1.5
.6.RELEASE.jar:
1.5
.6.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:
110) [spring-boot-actuator
-1.5
.6.RELEASE.jar:
1.5
.6.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
317) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:
127) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:
91) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:
114) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:
137) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:
111) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:
170) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:
63) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:
215) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:
116) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:
64) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:
105) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.context.
request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:
56) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:
331) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:
214) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:
177) [spring-security-web
-4.2
.3.RELEASE.jar:
4.2
.3.RELEASE]
at org.springframework.web.
filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:
346) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.web.
filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:
262) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.web.
filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:
99) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.web.
filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:
105) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.web.
filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:
81) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.cloud.sleuth.instrument.web.TraceFilter.doFilter(TraceFilter.java:
169) [spring-cloud-sleuth-core
-1.2
.4.RELEASE.jar:
1.2
.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.web.
filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:
197) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:
106) [spring-boot-actuator
-1.5
.6.RELEASE.jar:
1.5
.6.RELEASE]
at org.springframework.web.
filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
107) [spring-web
-4.3
.10.RELEASE.jar:
4.3
.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
193) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
166) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:
198) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:
96) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:
478) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
140) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:
80) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:
87) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
342) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:
799) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:
66) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:
868) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:
1455) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:
49) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:
1142) [na:
1.8
.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:
617) [na:
1.8
.0_131]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:
61) [tomcat-embed-core
-8.5
.16.jar:
8.5
.16]
at java.lang.Thread.run(Thread.java:
748) [na:
1.8
.0_131]
Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: SERVICE-FEIGN-HYSTRIX timed-out
and no fallback available.
at com.netflix.hystrix.AbstractCommand$
22.
call(AbstractCommand.java:
819) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at com.netflix.hystrix.AbstractCommand$
22.
call(AbstractCommand.java:
804) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$
4.onError(OperatorOnErrorResumeNextViaFunction.java:
140) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:
87) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:
87) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at com.netflix.hystrix.AbstractCommand$DeprecatedOnFallbackHookApplication$
1.onError(AbstractCommand.java:
1472) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at com.netflix.hystrix.AbstractCommand$FallbackHookApplication$
1.onError(AbstractCommand.java:
1397) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:
87) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.observers.Subscribers$
5.onError(Subscribers.java:
230) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeThrow.
call(OnSubscribeThrow.java:
44) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeThrow.
call(OnSubscribeThrow.java:
28) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.Observable.unsafeSubscribe(Observable.java:
10211) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDefer.
call(OnSubscribeDefer.java:
51) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDefer.
call(OnSubscribeDefer.java:
35) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.Observable.unsafeSubscribe(Observable.java:
10211) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach.
call(OnSubscribeDoOnEach.java:
41) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach.
call(OnSubscribeDoOnEach.java:
30) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeLift.
call(OnSubscribeLift.java:
48) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeLift.
call(OnSubscribeLift.java:
30) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeLift.
call(OnSubscribeLift.java:
48) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeLift.
call(OnSubscribeLift.java:
30) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.Observable.unsafeSubscribe(Observable.java:
10211) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach.
call(OnSubscribeDoOnEach.java:
41) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach.
call(OnSubscribeDoOnEach.java:
30) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.Observable.unsafeSubscribe(Observable.java:
10211) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach.
call(OnSubscribeDoOnEach.java:
41) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach.
call(OnSubscribeDoOnEach.java:
30) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeLift.
call(OnSubscribeLift.java:
48) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeLift.
call(OnSubscribeLift.java:
30) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.Observable.unsafeSubscribe(Observable.java:
10211) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach.
call(OnSubscribeDoOnEach.java:
41) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach.
call(OnSubscribeDoOnEach.java:
30) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeLift.
call(OnSubscribeLift.java:
48) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeLift.
call(OnSubscribeLift.java:
30) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.Observable.unsafeSubscribe(Observable.java:
10211) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$
4.onError(OperatorOnErrorResumeNextViaFunction.java:
142) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:
87) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:
87) ~[rxjava
-1.1
.10.jar:
1.1
.10]
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$
1$
1.run(AbstractCommand.java:
1154) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$
1.
call(HystrixContextRunnable.java:
45) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$
1.
call(HystrixContextRunnable.java:
41) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at org.springframework.cloud.sleuth.instrument.hystrix.SleuthHystrixConcurrencyStrategy$HystrixTraceCallable.
call(SleuthHystrixConcurrencyStrategy.java:
188) ~[spring-cloud-sleuth-core
-1.2
.4.RELEASE.jar:
1.2
.4.RELEASE]
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:
61) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$
1.tick(AbstractCommand.java:
1159) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at com.netflix.hystrix.util.HystrixTimer$
1.run(HystrixTimer.java:
99) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at java.util.concurrent.Executors$RunnableAdapter.
call(Executors.java:
511) ~[na:
1.8
.0_131]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:
308) ~[na:
1.8
.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$
301(ScheduledThreadPoolExecutor.java:
180) ~[na:
1.8
.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:
294) ~[na:
1.8
.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:
1142) [na:
1.8
.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:
617) [na:
1.8
.0_131]
...
1 common frames omitted
Caused by: java.util.concurrent.TimeoutException:
null
at com.netflix.hystrix.AbstractCommand.handleTimeoutViaFallback(AbstractCommand.java:
997) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at com.netflix.hystrix.AbstractCommand.access$
500(AbstractCommand.java:
60) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at com.netflix.hystrix.AbstractCommand$
12.
call(AbstractCommand.java:
610) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at com.netflix.hystrix.AbstractCommand$
12.
call(AbstractCommand.java:
601) ~[hystrix-core
-1.5
.12.jar:
1.5
.12]
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$
4.onError(OperatorOnErrorResumeNextViaFunction.java:
140) ~[rxjava
-1.1
.10.jar:
1.1
.10]
...
16 common frames omitted

故需要在SERVICE-ZUUL 的配置文件application.yml中增加hystrix的超时设置,

hystrix:     
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds:
60000

同样,对SERVICE-FEIGN-HYSTRIX的配置文件application.yml中也增加hystrix的超时设置

5,现在可以对各个服务进行web访问操作了,多次操作,把采样数据送给Zipkin server

6,输入http://localhost:9411/zipkin,打开Zipkin UI

点击左边红色圈的下拉框,可以列出我们跟踪的4个服务,调整Start time和End time ,再点击Find Traces 可以得到该服务的调用链数据,具体含义在此不做解释了,可以看到,每个服务调用的时长超过了一秒,印证了前面所说要加长服务超时设置。

点击右上角Dependencies 按钮,可以看到完整的调用链视图

还可以看到更多的信息

四、通过RabbitMQ传输数据在zipkin UI 上显示调用链的配置方法

该方法实际上就是Collector直接通过RabbitMQ的方式收集信息,Zipkin UI读取collector的信息,并展示,信息不落地到数据库。需要改造Zipkin Client(即被监控服务)的配置和Zipkin Server的配置。

 

以下介绍用rabbitMQ传输数据给zipkin server的方式

1,安装RabbitMQ

这个很简单,参考官方文档安装即可。本人在localhost 的win7上装了一个rabbitmq。并在后台以服务方式运行着。我们需要知道它的端口(默认为5672)、用户名和口令。通过浏览浏览可以对RabbitMQ进行管理(默认口令guest/guest)

2,改造zipkin-server

(1)改依赖,在pom.xml中去掉zipkin-server依赖,加上spring-cloud-sleuth-zipkin-stream和spring-cloud-starter-stream-rabbit依赖

io.zipkin.java
zipkin-autoconfigure-ui
org.springframework.cloud
spring-cloud-sleuth-zipkin-stream
org.springframework.cloud
spring-cloud-starter-stream-rabbit

(2)改配置,在application.yml中加上RabbitMQ的配置

spring:    
application:
name: zipkin-
server
rabbitmq:
host: localhost
port:
5672
username: guest
password: guest

(3)改代码,在主程序ZipkinServerApplication上加@EnableZipkinStreamServer注解,开启ZipkinStreamServer

//@EnableZipkinServer    
@EnableZipkinStreamServer

3,改造zipkin Client,对4个服务做以下的操作

(1)改依赖,在pom.xml中将spring-cloud-starter-zipkin改为spring-cloud-sleuth-zipkin-stream和spring-cloud-starter-stream-rabbit

org.springframework.cloud
spring-cloud-sleuth-zipkin-stream
org.springframework.cloud
spring-cloud-starter-stream-rabbit

(2)改配置,在application.yml中加上RabbitMQ的配置

spring:    
application:
name: service-feign-hystrix
zipkin:
base-url: http:
//localhost:9411
rabbitmq:
host: localhost
port:
5672
username: guest
password: guest

(3)代码不用改

4,重启各个服务,并进行访问操作

5,登录RabbitMQ管理界面,可以看到,有数据传输

6,打开Zipkin-UI ,同样可以看到有数据显示

五、将数据通过rabbitMQ写入Mysql再在zipkin UI 上显示调用链的配置方法

Zipkin支持Mysql、Elasticsearch、Cassandra等数据库存储,其实现方式很简单,就是把Zip server的存储方式改为相应的数据库存储方式,将原来rabbitMQ传到collector的数据存入相应的数据库,Zipkin UI 读取数据库的数据再展示,目的是让数据持久化。其架构图如图所示。

本章节介绍数据存入MYSQL的方法。

Zipkin client无需做任何更改,只需配好Mysql数据库和zipkin server即可

1,安装配置mysql,建数据库表,存储sleuth数据

具体如何安装配置mysql,在此不再赘述。我的数据库直接安装在本机。

在Mysql创建数据库`spring_cloud_zipkin`,连接数据库,创建相应对象以存储Sleuth信息。源码参见

CREATE      
TABLE
IF
NOT
EXISTS zipkin_spans (
`trace_id_high`
BIGINT
NOT
NULL
DEFAULT
0
COMMENT
'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id`
BIGINT
NOT
NULL,
`id`
BIGINT
NOT
NULL,
`name`
VARCHAR(
255)
NOT
NULL,
`parent_id`
BIGINT,
`debug`
BIT(
1),
`start_ts`
BIGINT
COMMENT
'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
`duration`
BIGINT
COMMENT
'Span.duration(): micros used for minDuration and maxDuration query'
)
ENGINE=
InnoDB ROW_FORMAT=COMPRESSED
CHARACTER
SET=utf8
COLLATE utf8_general_ci;
ALTER
TABLE zipkin_spans
ADD
UNIQUE
KEY(
`trace_id_high`,
`trace_id`,
`id`)
COMMENT
'ignore insert on duplicate';
ALTER
TABLE zipkin_spans
ADD
INDEX(
`trace_id_high`,
`trace_id`,
`id`)
COMMENT
'for joining with zipkin_annotations';
ALTER
TABLE zipkin_spans
ADD
INDEX(
`trace_id_high`,
`trace_id`)
COMMENT
'for getTracesByIds';
ALTER
TABLE zipkin_spans
ADD
INDEX(
`name`)
COMMENT
'for getTraces and getSpanNames';
ALTER
TABLE zipkin_spans
ADD
INDEX(
`start_ts`)
COMMENT
'for getTraces ordering and range';
CREATE
TABLE
IF
NOT
EXISTS zipkin_annotations (
`trace_id_high`
BIGINT
NOT
NULL
DEFAULT
0
COMMENT
'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id`
BIGINT
NOT
NULL
COMMENT
'coincides with zipkin_spans.trace_id',
`span_id`
BIGINT
NOT
NULL
COMMENT
'coincides with zipkin_spans.id',
`a_key`
VARCHAR(
255)
NOT
NULL
COMMENT
'BinaryAnnotation.key or Annotation.value if type == -1',
`a_value`
BLOB
COMMENT
'BinaryAnnotation.value(), which must be smaller than 64KB',
`a_type`
INT
NOT
NULL
COMMENT
'BinaryAnnotation.type() or -1 if Annotation',
`a_timestamp`
BIGINT
COMMENT
'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
`endpoint_ipv4`
INT
COMMENT
'Null when Binary/Annotation.endpoint is null',
`endpoint_ipv6`
BINARY(
16)
COMMENT
'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
`endpoint_port`
SMALLINT
COMMENT
'Null when Binary/Annotation.endpoint is null',
`endpoint_service_name`
VARCHAR(
255)
COMMENT
'Null when Binary/Annotation.endpoint is null'
)
ENGINE=
InnoDB ROW_FORMAT=COMPRESSED
CHARACTER
SET=utf8
COLLATE utf8_general_ci;
ALTER
TABLE zipkin_annotations
ADD
UNIQUE
KEY(
`trace_id_high`,
`trace_id`,
`span_id`,
`a_key`,
`a_timestamp`)
COMMENT
'Ignore insert on duplicate';
ALTER
TABLE zipkin_annotations
ADD
INDEX(
`trace_id_high`,
`trace_id`,
`span_id`)
COMMENT
'for joining with zipkin_spans';
ALTER
TABLE zipkin_annotations
ADD
INDEX(
`trace_id_high`,
`trace_id`)
COMMENT
'for getTraces/ByIds';
ALTER
TABLE zipkin_annotations
ADD
INDEX(
`endpoint_service_name`)
COMMENT
'for getTraces and getServiceNames';
ALTER
TABLE zipkin_annotations
ADD
INDEX(
`a_type`)
COMMENT
'for getTraces';
ALTER
TABLE zipkin_annotations
ADD
INDEX(
`a_key`)
COMMENT
'for getTraces';
ALTER
TABLE zipkin_annotations
ADD
INDEX(
`trace_id`,
`span_id`,
`a_key`)
COMMENT
'for dependencies job';
CREATE
TABLE
IF
NOT
EXISTS zipkin_dependencies (
`day`
DATE
NOT
NULL,
`parent`
VARCHAR(
255)
NOT
NULL,
`child`
VARCHAR(
255)
NOT
NULL,
`call_count`
BIGINT,
`error_count`
BIGINT
)
ENGINE=
InnoDB ROW_FORMAT=COMPRESSED
CHARACTER
SET=utf8
COLLATE utf8_general_ci;
ALTER
TABLE zipkin_dependencies
ADD
UNIQUE
KEY(
`day`,
`parent`,
`child`);

结果如下

C:\Users\     
91678>mysql -u root -p spring_cloud_zipkin
Enter
password: ******
Welcome to the MySQL monitor. Commands
end with ;
or \g.
Your MySQL connection id is
7
Server
version:
5.7.
19 MySQL Community Server (GPL)
Copyright (c)
2000,
2015, Oracle
and/
or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation
and/
or its
affiliates. Other names may be trademarks of their respective
owners.
Type
'help;'
or
'\h'
for help. Type
'\c' to clear the current input statement.
mysql> show tables;
+-------------------------------+
| Tables_in_spring_cloud_zipkin |
+-------------------------------+
| zipkin_annotations |
| zipkin_dependencies |
| zipkin_spans |
+-------------------------------+
3 rows
in set (
0.
00 sec)
mysql>

2,改造Zipkin server

(1)加依赖,在POM.XML增加mysql JDBC相关依赖

mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-jdbc

(2)改配置,增加了DataSource配置和zipkin的storage配置

server:    
port:
9411
spring:
application:
name: zipkin-server
rabbitmq:
host: localhost
port:
5672
username: guest
password: guest
datasource:
url: jdbc:mysql:
//localhost:3306/spring_cloud_zipkin
username: root
password: abc123
driver-
class-
name: com.mysql.jdbc.Driver
zipkin:
storage:
type: mysql
eureka:
client:
service-url:
defaultZone: http:
//localhost:8761/eureka/

(3)代码不用改

3,重启各个服务,并进行访问操作

4,登录RabbitMQ管理界面,可以看到,有数据传输

5,查看mysql数据库,可以看到有新的Sleuth信息被存储进去

6,打开Zipkin-UI ,同样可以看到有数据显示

六、将数据通过rabbitMQ写入ElasticSearch再在zipkin UI 上显示调用链的配置方法

如第五章所言,Zipkin支持Mysql、Elasticsearch、Cassandra等数据库存储。以下是将rabbitMQ传到collector的数据存入ElasticSearch数据库,Zipkin UI 读取数据库的数据再展示。架构图同第五章。

修改第五章的相应配置,步骤如下

1,安装配置ElasticSearch,存储sleuth数据。安装方法参见本人博客

2,改造Zipkin server

(1)加依赖,在POM.XML去处第五章的mysql相关依赖,增加ElasticSearch相关依赖

io.zipkin.java
zipkin
io.zipkin.java
zipkin-autoconfigure-storage-elasticsearch-http
1.28.0

(2)改配置,在application.yml去除mysql相关配置,加上Zipkin的配置,配置了zipkin的存储类型为elasticsearch,使用的StorageComponent为elasticsearch,然后需要配置elasticsearch,包括hosts,可以配置多个,用“,”隔开;index为zipkin等,具体配置如下:

server:    
port:
9411
spring:
application:
name: zipkin-server
rabbitmq:
host: localhost
port:
5672
username: guest
password: guest
zipkin:
storage:
type: elasticsearch
StorageComponent: elasticsearch
elasticsearch:
cluster: elasticsearch
max-requests:
30
index: zipkin
index-shards:
3
index-replicas:
1
hosts:
192.168.
122.10:
9200
eureka:
client:
service-url:
defaultZone: http:
//localhost:8761/eureka/

此处hosts192.168.122.10为我的ELK服务的虚机地址。

(3)代码不用改

3,重启各个服务,并进行访问操作

4,登录RabbitMQ管理界面,可以看到,有数据传输

5,查看kibana,可以看到ElasticSearch数据库有新的以zipkin为index 的Sleuth信息被存储进去

6,打开Zipkin-UI ,同样可以看到有数据显示

总结

本文详细介绍了Spring cloud zipkin通过http和rabbitMQ收集sleuth信息到collector,存入到mysql和ElasticSearch,并通过Zipkin UI展示的方法。

本文代码在github 上可以下载:

 

注:本文参考了方志鹏的博客

转载地址:https://blog.csdn.net/HD243608836/article/details/102505853 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:SpringBoot获取音频文件时长
下一篇:springboot中方法调用链路追踪——Zipkin快速开始

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月25日 14时04分44秒