链路追踪 trace 快速入门

举报
李路的路 发表于 2021/07/03 13:48:28 2021/07/03
【摘要】 基础应用Spring Cloud Sleuth为服务之间调用提供链路追踪。通过Sleuth可以很清楚地了解到一个服务请求经过了哪些服务,每个服务处理花费了多长。从而可以很方便的理清各微服务间的调用关系。此外Sleuth还可以帮助我们进行耗时分析,通过Sleuth可以很方便的了解到每个采样请求的耗时,从而分析出哪些服务调用比较耗时;可视化错误,对于程序未捕捉的异常,可以通过集成Zipkin服...

基础应用

Spring Cloud Sleuth为服务之间调用提供链路追踪。通过Sleuth可以很清楚地了解到一个服务请求经过了哪些服务,每个服务处理花费了多长。从而可以很方便的理清各微服务间的调用关系。此外Sleuth还可以帮助我们进行耗时分析,通过Sleuth可以很方便的了解到每个采样请求的耗时,从而分析出哪些服务调用比较耗时;可视化错误,对于程序未捕捉的异常,可以通过集成Zipkin服务界面上看到;链路优化,对于调用比较频繁的服务,可以针对这些服务实施一些优化措施。

Spring Cloud Sleuth 特性

Spring Cloud Sleuth具有如下的特性:

  • 提供对常见分布式跟踪数据模型的抽象:traces,spans(形成DAG),annotations和键值注解。 Spring Cloud Sleuth虽然基于HTrace,但与Zipkin(Dapper)兼容。
  • Sleuth记录了耗时操作的信息以辅助延时分析。通过使用Sleuth,可以定位应用中的耗时原因。
  • 为了不写入太多的日志,以至于使生产环境的应用程序崩溃,Sleuth做了如下的工作:
    • 生成调用链的结构化数据
    • 包括诸如自定义的织入层信息,比如HTTP
    • 包括采样率配置以控制日志的容量
    • 查询和可视化完全兼容Zipkin
  • 为Spring应用织入通用的组件,如servlet filter、Zuul过滤器和Feign客户端等等
  • Sleuth可以在进程之间传播上下文(也称为背包)。 因此,如果在Span上设置了背包元素,它将通过HTTP或消息传递下游,发送到其他进程
  • Spring Cloud Sleuth 实现了OpenTracing的规范。OpenTracing通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的实现

项目准备

下面通过两个服务之间的相互调用,演示链路监控的场景。前期需要准备的项目有三个:

  • Eureka Server:服务注册Server,作为其他客户端服务的注册中心;
  • Sleuth Client A:客户端服务A,注册到Eureka Server。对外提供两个接口,一个接口暴露给客户端服务A,另一个接口调用客户端服务B,客户端服务之间通过Feign进行http调用;
  • Sleuth Client B:同上。

Eureka Server

首先,依赖需要引入Netflix Eureka Server。

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

其次,配置Eureka Server的服务端信息。

spring:
  application:
    name: eureka-server-standalone
server:
  port: 8761
eureka:
  instance:
    hostname: standalone
    instance-id: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}

如上配置文件所示,我们配置了单机模式的Eureka Server,服务器的端口号为8761。

最后,添加应用程序的入口类。

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

如上三步完成,我们的注册服务即可以正常启动。

Sleuth Client A

首先,也是引入客户端服务A所需要的依赖。

    <dependencies>
        <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.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

需要的基本依赖为:注册客户端、声明式客户端组件openfeign和Spring Boot Web包。

其次,客户端服务A的配置文件如下:

eureka:
  instance:
    instance-id: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/, http://localhost:8762/eureka/

spring:
  application:
    name: service-a
server:
  port: 9002

上述配置声明了服务名,feign通过服务名进行服务实例调用,指定了客户端服务A的端口号9002。A还需要注册到Eureka Server。

然后,就是提供两个接口,如下为其实现:

@RestController
@RequestMapping("/api")
public class ServiceAController {
    @Autowired
    ServiceBClient serviceBClient;

    @GetMapping("/service-a")
    public String fromServiceA(){
        return "from serviceA";
    }
    @GetMapping("/service-b")
    public String fromServiceB(){
        return serviceBClient.fromB();
    }
}

服务A提供了/service-b接口,可以调用服务B,feign客户端的实现如下。/service-a接口用以给服务B调用。

@FeignClient("service-b")
public interface ServiceBClient {

    @RequestMapping(value = "/api/service-b")
    public String fromB();
}

feign客户端的注解中,指定了要调用的服务B的serviceId为service-b

最后,应用程序的入口类如下:

@SpringBootApplication
@EnableFeignClients
public class ChapterClientServiceaApplication {

    public static void main(String[] args) {
        SpringApplication.run(ChapterClientServiceaApplication.class, args);
    }
}

@EnableFeignClients注解会扫描那些声明为feign客户端的接口。

如上,客户端服务A的实现大功告成。

Sleuth Client B

客户端服务B与A的实现基本类似,A与B之间实现互调。这里略过实现。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。