SpringCloud(十五)springCloud sleuth 分布式链路跟踪

前言:

    在为服务中,各个为服务之间存在着调用关系,spring cloud sleuth就是追踪整条调用链的。


一些感念:

  • Span:基本工作单元,例如,在一个新建的span中发送一个RPC等同于发送一个回应请求给RPC,span通过一个64位ID唯一标识,trace以另一个64位ID表示,span还有其他数据信息,比如摘要、时间戳事件、关键值注释(tags)、span的ID、以及进度ID(通常是IP地址)
    span在不断的启动和停止,同时记录了时间信息,当你创建了一个span,你必须在未来的某个时刻停止它。
  • Trace:一系列spans组成的一个树状结构,例如,如果你正在跑一个分布式大数据工程,你可能需要创建一个trace。
  • Annotation:用来及时记录一个事件的存在,一些核心annotations用来定义一个请求的开始和结束
    • cs - Client Sent -客户端发起一个请求,这个annotion描述了这个span的开始
    • sr - Server Received -服务端获得请求并准备开始处理它,如果将其sr减去cs时间戳便可得到网络延迟
    • ss - Server Sent -注解表明请求处理的完成(当请求返回客户端),如果ss减去sr时间戳便可得到服务端需要的处理请求时间
    • cr - Client Received -表明span的结束,客户端成功接收到服务端的回复,如果cr减去cs时间戳便可得到客户端从服务端获取回复的所有所需时间
      将Span和Trace在一个系统中使用Zipkin注解的过程图形化:

代码:

在springboot2.0,springcloud Finchley版本,不允许自己建zipkin server了,可以用jar包自己跑,也可以直接用docker运行,https://github.com/openzipkin/zipkin#quick-start 地址。

我就用docker了

docker run -d -p 9411:9411 --name zipkin openzipkin/zipkin

启动后访问 http://192.168.94.151:9411/zipkin/




然后创建一个eureka,一个两个有调用关系的为服务

eureka  pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springcloud16-zipkin</artifactId>
        <groupId>com.xhx.springcloud</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-server</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>

application.yml

spring:
  application:
    name: eureka-server
server:
  port: 8761
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      default-zone: http://${eureka.instance.hostname}:${server.port}/eureka

启动类:

package com.xhx.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * xuhaixing
 * 2018/6/16 16:34
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class,args);
    }
}

服务提供者  user-service:

pom.xml,增加sleuth和zipkin两个包

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springcloud16-zipkin</artifactId>
        <groupId>com.xhx.springcloud</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
    </dependencies>

</project>

application.yml,base-url指定zipkin的地址

spring:
  application:
    name: user-service
  zipkin:
    base-url: http://192.168.94.151:9411
    #discovery-client-enabled: true
   # service:
      #name: zipkin-service
    enabled: true
server:
  port: 8080
eureka:
  client:
    service-url:
      default-zone: http://locahost:8761/eureka
feign:
  hystrix:
    enabled: true

启动类:

package com.xhx.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;


/**
 * xuhaixing
 * 2018/6/16 17:04
 */
@SpringCloudApplication
@EnableFeignClients
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class,args);
    }
}
提供接口的controller
package com.xhx.springcloud.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * xuhaixing
 * 2018/6/16 17:09
 */
@RestController
@RequestMapping(value = "user")
public class UserController {


    @RequestMapping(value = "getUserInfo",method = RequestMethod.POST)
    public Map<String, String> getUserInfo(){
        Map<String,String> user = new HashMap<>();
        user.put("name","xuhaixing");
        user.put("gender","man");
        return user;
    }
}

服务消费者

pom.xml和前面一样加入sleuth和zipkin

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springcloud16-zipkin</artifactId>
        <groupId>com.xhx.springcloud</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
        </dependency>

    </dependencies>

</project>

application.yml

probability是被zipkin收集的概率,1为全部收集,因为现在是直接用http方式发送数据并且放在内存中,所以会影响性能。可以用消息队列或者mysql收集服务链路信息。

spring:
  application:
    name: order-service
  zipkin:
      #discovery-client-enabled: true
      #service:
        #name: zipkin-service
      enabled: true
      base-url: http://192.168.94.151:9411
  sleuth:
    sampler:
      probability: 1
server:
  port: 8086
eureka:
  client:
    service-url:
      default-zone: http://locahost:8761/eureka
feign:
  hystrix:
    enabled: true

feign

package com.xhx.springcloud.api;

import com.alibaba.fastjson.JSONObject;
import com.xhx.springcloud.hystrix.UserInfoApiHytrix;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.Map;

/**
 * xuhaixing
 * 2018/6/16 17:19
 */
@FeignClient(value = "user-service",path = "user",fallback = UserInfoApiHytrix.class)
public interface UserInfoApi {
    @RequestMapping(value = "getUserInfo",method = RequestMethod.POST)
    JSONObject getUserInfo();
}

controller

package com.xhx.springcloud.controller;

import com.alibaba.fastjson.JSONObject;
import com.xhx.springcloud.api.UserInfoApi;
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 java.util.Optional;

/**
 * xuhaixing
 * 2018/6/16 17:19
 */
@RestController
@RequestMapping(value = "order")
public class OrderController {

    @Autowired
    private UserInfoApi userInfoApi;

    @RequestMapping(value = "getUserOrder",method = RequestMethod.POST)
    public JSONObject getUserOrder(){
        JSONObject userInfo = userInfoApi.getUserInfo();
        Optional.ofNullable(userInfo).ifPresent(user->user.put("orderMoney",999));
        return userInfo;
    }
}

hystrix

package com.xhx.springcloud.hystrix;

import com.alibaba.fastjson.JSONObject;
import com.xhx.springcloud.api.UserInfoApi;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * xuhaixing
 * 2018/6/16 17:20
 */
@Component
public class UserInfoApiHytrix implements UserInfoApi {
    @Override
    public JSONObject getUserInfo() {
        return null;
    }
}

请求一下


打开zipkin






猜你喜欢

转载自blog.csdn.net/u012326462/article/details/80719641
今日推荐