跳至主要內容

SpringCloudSleuth

soulballad微服务SpringCloud NetfilxSpringCloud约 1476 字大约 5 分钟

Spring Cloud Sleuth

基础

Google Dapper

Spring Cloud Sleuth 使用

项目名称 spring-cloud-sleuth-demo

  1. 引入 maven 依赖

    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-sleuth</artifactId>
    </dependency>
    
  2. 自定义 web

    @RestController
    public class DemoController {
    
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        @GetMapping("/hello")
        public String hello() {
            String result = "hello, world";
            logger.info("{} hello() : {}", getClass().getSimpleName(), result);
            return result;
        }
    }
    
  3. application.properties 配置

    # 应用名
    spring.application.name=spring-cloud-sleuth
    
  4. 访问 http://localhost:8080/hello 日志变化

    1570538564196

日志发生的变化

当应用ClassPath 下存在org.springframework.cloud:spring-cloud-starter-sleuth时候,日志会发生调整。

整体流程

spring-cloud-starter-sleuth 会自动装配一个名为TraceFilter 组件(在 Spring WebMVC DispatcherServlet 之前),它会增加一些 slf4j MDC

MDCopen in new window : Mapped Diagnostic Context

org.springframework.cloud:spring-cloud-starter-sleuth 会调整当前日志系统(slf4j)的 MDC Slf4jSpanLogger#logContinuedSpan(Span):

	@Override
	public void logContinuedSpan(Span span) {
		MDC.put(Span.SPAN_ID_NAME, Span.idToHex(span.getSpanId()));
		MDC.put(Span.TRACE_ID_NAME, span.traceIdString());
		MDC.put(Span.SPAN_EXPORT_NAME, String.valueOf(span.isExportable()));
		setParentIdIfPresent(span);
		log("Continued span: {}", span);
	}

Spring Cloud Zipkin 使用

https://zipkin.io/

  1. 引入 maven 依赖

    <!-- Zipkin 服务器 -->
    <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-server</artifactId>
        <version>2.11.9</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zipkin</artifactId>
        <version>2.1.4.RELEASE</version>
    </dependency>
    <!-- Zipkin UI -->
    <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-autoconfigure-ui</artifactId>
        <version>2.11.9</version>
    </dependency>
    
  2. 激活 zipkin 服务器

    @SpringBootApplication
    @EnableZipkinServer
    public class SpringCloudZipkinDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringCloudZipkinDemoApplication.class, args);
        }
    
    }
    
  3. application.properties 配置

    spring.application.name=spring-cloud-zipkin-server
    server.port=23456
    
  4. 浏览器访问 http://localhost:23456

    1570538917015

Zipkin 整合 sleuth

修改 spring-cloud-sleuth-demo

HTTP 收集(HTTP 调用)

  1. 引入 zipkin 依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zipkin</artifactId>
        <version>2.1.4.RELEASE</version>
    </dependency>
    
  2. 修改 application.properties 配置

    添加 zipkin 服务器配置

    ## Zipkin 服务器配置
    zipkin.server.host=localhost
    zipkin.server.port=23456
    # 增加 zipkin 服务器地址
    spring.zipkin.base-url=\
      http://${zipkin.server.host}:${zipkin.server.port}/
    
  3. 浏览器查看

    先刷新几遍 http://localhost:8080/hello,然后再到 http://localhost:23456 去查看,可以发现 zipkin 中已有有了 spring-cloud-seluth 服务

    1570540050284

Zipkin 整合Spring Cloud服务

201910071724319761

端口信息

spring-cloud-zuul 端口:7070

person-client 端口:8080

person-service 端口:9090

Eureka Server 端口:12345

Zipkin Server 端口:23456

启动各项服务

  1. spring-cloud-zipkin-demo
  2. spring-cloud-feign-eureka
  3. spring-cloud-zuul-config-server
  4. spring-cloud-feign-demo/person-service
  5. spring-cloud-feign-demo/person-client
  6. spring-cloud-zuul-demo

注册到 eureka 上的各项服务

1570541267284

Sleuth 整合 eureka

spring-cloud-sleuth-demo 改造

  1. 增加 Eureka 客户端依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  2. 激活 Eureka 客户端

    @SpringBootApplication
    @EnableDiscoveryClient
    public class SpringCloudSleuthDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringCloudSleuthDemoApplication.class, args);
        }
    
        // 配置 负载均衡
        @LoadBalanced
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    
  3. 增加 eureka 配置,同时调整端口为 6060,避免冲突

    server.port=6060
    eureka.client.service-url.defaultZone=\
      http://localhost:12345/eureka
    
  4. 在 controller 中调用,调整代码连接 spring-cloud-zuul

    调用链路:spring-cloud-sleuth->zuul->person-client->person-service

    @RestController
    public class DemoController {
    
        private final Logger logger = LoggerFactory.getLogger(getClass());
    
        private final RestTemplate restTemplate;
    
        @Autowired
        public DemoController(RestTemplate restTemplate) {
            this.restTemplate = restTemplate;
        }
    
        @GetMapping("/hello")
        public String hello() {
            String result = "hello, world";
            logger.info("{} hello() : {}", getClass().getSimpleName(), result);
            return result;
        }
    
        /**
         * 完整的调用链路
         * spring-cloud-sleuth
         * ->zuul
         * ->person-client
         * ->person-service
         */
        @GetMapping("/to/zuul/person-client/person/find/all")
        public Object toZuul() {
            // spring-cloud-zuul: 7070
            logger.info("spring-cloud-sleuth#toZuul");
            String url = "http://spring-cloud-zuul/person-client/person/find/all";
            return restTemplate.getForObject(url, Object.class);
        }
    }
    
  5. eureka 注册成功

    1570541429118

  6. 测试结果

    http://localhost:6060//to/zuul/person-client/person/find/all

    1570543603325

Zipkin 整合其他服务

  • 涉及服务

    • spring-cloud-zuul
    • person-client
    • person-service
  • 整合步骤

    • 添加 maven 依赖

      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-zipkin</artifactId>
          <version>2.1.4.RELEASE</version>
      </dependency>
      
    • 配置 zipkin 服务地址

      ## Zipkin 服务器配置
      zipkin.server.host = localhost
      zipkin.server.port = 23456
      
      ## 增加 ZipKin 服务器地址
      spring.zipkin.base-url = \
        http://${zipkin.server.host}:${zipkin.server.port}/
      
  • 整合结果

    1570543716279

  • 完整调用链路

    1570619821932

Spring Cloud Stream 收集(消息)

调整spring-cloud-zipkin-server 通过 Stream 来收集
增加 Maven 依赖
<!-- Zipkin 服务器通过Stream 收集跟踪信息 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>
</dependency>
<!-- 使用 Kafka 作为 Stream 服务器 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-stream-binder-kafka</artifactId>
</dependency>

激活 Zipkin Stream
package com.gupao.springcloudzipkinserverdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.sleuth.zipkin.stream.EnableZipkinStreamServer;
import zipkin.server.EnableZipkinServer;

@SpringBootApplication
//@EnableZipkinServer
@EnableZipkinStreamServer
public class SpringCloudZipkinServerDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringCloudZipkinServerDemoApplication.class, args);
	}
}
启动 Zookeeper
启动 Kafka 服务器
启动spring-cloud-zipkin-server
调整 spring-cloud-zuul
增加依赖
<!-- 添加 sleuth Stream 收集方式 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-sleuth-stream</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- Kafka Binder -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-stream-binder-kafka</artifactId>
</dependency>

注意把前面 HTTP 上报URL配置注释:

### 增加 ZipKin 服务器地址
#spring.zipkin.base-url = \
#  http://${zipkin.server.host}:${zipkin.server.port}/

问答部分

  • 只有第一个被访问的应用的pom引用了spring-cloud-starter-sleuth包么?后面的应用spanid是怎么生成的?上报是汇集到一起上报么?

    答:每个应用都需要依赖spring-cloud-starter-sleuth。SpanId 是当前应用生成的,Trace ID 是有上个应用传递过来(Spring Cloud 通过请求头Headers)

  • sleuth配合zipkin主要解决的是分布式系统下的请求的链路跟踪,这么理解没错吧?

    答:可以这么理解,问题排查、性能、调用链路跟踪

  • sleuth 与 eureka 没关联吧?

    答:没有直接关系,Sleuth 可以利用 Eureka 做服务发现

  • 生产上类sleuth的log日志应该看哪些资料?opentsdb,也有调用链路等相关信息么?

    答:OpenTsdb 主要是存储 JSON 格式,存放Metrics 信息

  • 排查问题是根据traceid来查找有所日志吧

    答:可以通过TraceId 查找调用链路,通过 Span Id 定位在什么环节

  • 整合显示是sleuth做的,zipkin用来收集信息对吧?

    答:zipkin 是一种用整合方式

  • 问个题外话,两个系统对接需要通过json进行数据传输,但是两个系统之间的json数据格式是不同的,有没有好一点的开源项目可以解决这个问题,类似xslt转换xml的方式。

    答:A -> B, data1 , B -> A data2, 接受方使用Map。JSON Path

    {"id":1,
    	abc:{
    		"name":"xiaomage",
          	 "age":32
    	}
    }
    
    
上次编辑于:
贡献者: soulballad