分布式链路追踪和监控

摘要:指跟踪请求在分布式系统中的流转路径与状态。在分布式系统中,记录请求的处理过程、并聚合展示。


目录

[TOC]

分布式链路追踪和监控

分布式链路追踪(Tracing):指跟踪请求在分布式系统中的流转路径与状态。在分布式系统中,记录请求的处理过程、并聚合展示。

  • 请求在系统中的完整生命周期,包括经过的服务、调用的操作以及每个操作的延迟等。如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等。

  • 用途:用于故障诊断、容量预估、性能瓶颈分析、优化系统的性能、调用链路梳理等。

  • 技术实现上包含了数据埋点、采集、存储、分析、可视化等环节,形成了一套完整的技术体系。

基本概念

  • Trace(追踪):一个完整的用户请求流程,从用户发起请求开始,到请求结束。一个追踪包含多个 Span。
  • Span(跨度):一种表示工作单元的结构,通常对应着请求经过的某个服务或者操作,每个Span包含以下信息:
    1. Span ID:唯一标识当前Span
    2. Trace ID:标识属于同一个Trace的所有Span
    3. 父Span ID:如果当前Span由另一个Span引发,则会记录父Span ID
    4. 时间戳、标签和日志

基本原理

  1. 在分布式应用的接口方法上设置一些观察点
  2. 然后在入口节点给每个请求分配一个全局唯一的标识 TraceId(类似快递单号),
  3. 当请求流经这些观察点时就会记录一行对应的链路日志(包含链路唯一标识,接口名称,时间戳,主机信息等)。
  4. 最后通过 TraceId 将一次请求的所有链路日志进行组装,就可以还原出该次请求的链路轨迹。

img

Actuator

应用在部署在生产环境下,需要考虑应用的管理与监控。例如说,应用是否健康存活、应用的 JVM 监控信息、服务器的监控信息(CPU、内存、磁盘等等)。

Spring Boot Actuator 监控端点提供 HTTP API 接口,返回应用的审计(auditing)、健康状况(health)和指标(metrics)等数据。

  • 没有 UI。

内置端点

org.springframework.boot.actuate 包下,可以看到 Actuator 已经和多个框架进行集成,提供内置端点

内置端点有:

Spring Boot Admin 监控中心

Spring Boot Admin 是由 codecentric 组织开发的开源项目,可以管理和监控 Spring Boot 项目。

  • 可以对SpringBoot应用的各项指标进行监控,可以作为微服务架构中的监控中心来使用。
  • SpringBoot应用可以通过Actuator来暴露应用运行过程中的各项指标,Spring Boot Admin通过这些指标来监控应用,然后通过图形化界面呈现出来。

  • 不仅可以监控单体应用,还可以和Spring Cloud的注册中心相结合来监控微服务应用。

分为客户端和服务端两部分:

  • 客户端添加到 Spring Boot(被监控和管理的)应用程序,有两种方式注册到 Spring Boot Admin Server 上。
    1. 增加暴漏相关信息的 HTTP 接口,使用 Spring Boot Admin Client 库,通过 HTTP 调用注册到 Spring Boot Admin Server 服务端上。
    2. 首先,注册到 Spring Cloud 集成的注册中心;然后 Spring Boot Admin Server 通过注册中心获取到被监控和管理的应用程序。
  • 而 Spring Boot Admin Server 通过 Vue.js 程序监控信息进行可视化呈现。并且支持多种事件通知操作。

优缺点

优点:总得来说,算是不错的轻量级的监控工具,只需要极少量的配置,就可以完成 Spring Boot 的应用的监控、管理、甚至说告警。

  • 一般情况下,如果想要快速搭建一个监控工具,算是一个不错的选择。

缺点: 比较大的一个问题,是不会主动采集 Spring Boot 应用的 Metrics 指标数据,记录到存储器中。

更多的时候,可以把 Spring Boot Admin 看成 Spring Boot 应用的 Actuator 的网关,负责将 UI 界面需要的数据,转发到对应的应用的 Actuator 的端点,从而可以进行不同应用实例的监控与管理。

  • 也因此,把 Spring Boot Admin 定义为监控工具

通过 HTTP 调用注册

被监控和管理的应用程序,通过方式一,使用 Spring Boot Admin Client 库,通过 HTTP 调用注册到 Spring Boot Admin Server 上。

Spring Boot Admin Server

引入依赖

1
2
3
4
5
6
7
8
9
10
11
<!-- 实现对 Spring Boot Admin Server 的自动化配置 -->
<!--
  包含 1. spring-boot-admin-server :Server 端
       2. spring-boot-admin-server-ui :UI 界面
       3. spring-boot-admin-server-cloud :对 Spring Cloud 的接入
        -->
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-server</artifactId>
    <version>2.2.0</version>
</dependency>

AdminServerApplication

  • 在类上,添加了 @EnableAdminServer 注解,表示开启 Spring Boot Admin Server 功能。

使用浏览器,打开 http://127.0.0.1:8080/ 地址,访问 Spring Boot Admin Server UI 。

Spring Boot Admin Client

引入依赖

1
2
3
4
5
6
7
8
9
10
11
12
 <!-- 实现对 Actuator 的自动化配置 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- 实现对 Spring Boot Admin Client 的自动化配置 -->
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.2.0</version>
</dependency>

配置文件

application.yml 中,添加 Spring Boot Admin Client 配置。

  • 配置 management.endpoints.web.exposure.include = * ,设置 Spring Boot Actuator 所有端点都开放。
  • 配置 spring.application.name = demo-application ,设置应用名。
  • 重点】配置 spring.boot.admin.client.url = http://127.0.0.1:8080 ,设置 Spring Boot Admin Server 地址
  • 配置 server.port = 18080 ,设置自定义 Server 端口,避免和 Spring Boot Admin Server 端口冲突。

友情提示,如果使用方式一来注册,可以使用 Nginx 做多个 Spring Boot Admin 节点的负载均衡,而项目中配置该负载均衡的地址,从而实现 Spring Boot Admin 的高可用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
management:
  endpoints:
    # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类
    web:
      exposure:
        include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。

spring:
  application:
    name: demo-application # 应用名
  boot:
    admin:
      client:
        url: http://127.0.0.1:8080 # Spring Boot Admin Server 地址

server:
  port: 18080 # 设置自定义 Server 端口,避免和 Spring Boot Admin Server 端口冲突。

Spring Boot Admin 使用

使用

使用浏览器:

  • 再次打开 http://127.0.0.1:8080/ 地址,会发现该应用注册上了。

  • 打开 http://127.0.0.1:8080/journal 地址,可以看到日志报表。

功能介绍

Spring Boot Admin 提供的功能挺强大的,基本所有 Actuator 端点提供的功能,都开发了相应的 UI 界面。

可以提供应用的以下监控信息:

  1. Insights监控应用运行过程中的概览信息。
    1. Details 细节:度量指标信息,对应多个 Actuator 端点,拼凑而成的界面。涉及元数据、健康状态、进程、线程、JVM 内存、GC,Tomcat。
    2. Metrics 性能;对应 metrics 端点,可见《芋道 Spring Boot 监控端点 Actuator 入门》「6. metrics 端点」小节。
      • 通过该界面,可以选择要查询的 Metrics ,点击「Add Metrics」按钮,确认添加。
    3. 环境变量信息,比如系统属性、系统环境变量以及应用配置信息;
    4. 查看所有创建的 Bean(.class 类)信息;
    5. 查看应用中的所有配置信息;
    6. 查看可以访问的Web端点;
  2. Loggers:查看应用运行日志配置。可以查看和修改 Logger 配置。
  3. JVM:
    1. JMX:Java 管理扩展。
    2. Thread Dump:线程转储。从界面开始,每秒读取一次线程快照。
    3. Heap Dump:内存转储。
  4. Mappings 映射:对应 loggers 端点。
    • dispatcherServlet对应的方法、返回内容类型、处理程序;查看HTTP跟踪信息
  5. 缓存管理。

基于 Spring Cloud 注册中心

采用方式二,基于 Spring Cloud 支持的注册中心,来实现 Spring Boot Admin 对注册到注册中心的应用,进行监控与管理。这里,采用 Eureka 作为注册中心。整个示例的过程如下:

  1. 首先,创建 lab-35-admin-02-eurekaserver 项目,启动 Eureka Server 注册中心
  2. 然后,创建 lab-35-admin-02-demo-application 项目,启动示例项目作为应用,注册到 Eureka Server 上。
  3. 最后,我创建 lab-35-admin-02-adminserver 项目,启动 Spring Boot Admin Server 监控工具。之后,Spring Boot Admin Server 从 Eureka Server 获取到示例项目的两个应用节点,进行监控与管理。

Eureka Server

Eureka Client

Spring Boot Admin Server

通过引入 spring-cloud-starter-netflix-eureka-client,实现从 Eureka Server 拉取注册中心,从而获取到要监控与管理的应用。

配置文件

application.yml 中,添加 Eureka Client 配置,如下:

  • 配置 eureka.client.service-url.defaultZone = http://127.0.0.1:8761/eureka ,设置 Eureka Server 为我们在「4.1 Eureka Server」所启动的。
  • 配置 eureka.client.register-with-eureka = false,无需使用 Eureka Client 注册到 Eureka Server。😈 我们只要从 Eureka Server 拉取注册信息即可。
1
2
3
4
5
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka
    register-with-eureka: false # 不注册到 Eureka 中

Admin Server 安全认证

考虑到安全性,需要给 Spring Boot Admin Server 增加安全认证,需要经过登录之后,才可以使用。

  • 可以通过整合 Spring Security 框架,快速的实现安全认证的功能。

SecurityConfig

  • 在类上,添加 @EnableWebFluxSecurity 注解,开启 Security 对 WebFlux 的安全功能。😈 因为 Spring Boot Admin Server 是基于 WebFlux 实现的,所以不能按照我们之前针对 Servlet 的配置方式。
  • #userDetailsService() 方法,创建了 MapReactiveUserDetailsService 对象。在其中,我们配置了一个「user/user」账号。如果胖友有更多用户的诉求,这里可以继续创建。
  • #springSecurityFilterChain(...) 方法,创建了SecurityWebFilterChain 对象。在其中,我们设置了权限配置、登录页面、登出地址、禁用 csrf 。

Admin Client 安全认证

可以通过整合 Spring Security 框架,给 Spring Boot Actuator 的端点增加安全认证的功能。

  • 这就意味着,如果 Spring Boot Admin Server 访问 Spring Boot Actuator 的端点时,也需要知道该端点的账号密码。

「2. 快速入门」方式一中,可以采用 Spring Boot Admin Client 上报 Actuator 端点的账号密码给 Spring Boot Admin Server 。在 application.yml 配置文件中,修改如下即可:

1
2
3
4
5
6
spring.boot.admin.client:
    url: http://localhost:8080
    instance:
      metadata:
        user.name: ${spring.security.user.name}
        user.password: ${spring.security.user.password}

「4. 基于 Spring Cloud 注册中心」方式二中,应用在注册自己到注册中心时,同时在实例的 metadata 元数据中带上 Actuator 端点的账号密码。在 application.yml 配置文件中,修改如下即可:

1
2
3
4
5
eureka:
  instance:
    metadata-map:
      user.name: ${spring.security.user.name}
      user.password: ${spring.security.user.password}

监控告警

在 Spring Boot Admin 中,已经集成告警功能。例如说,被监控的应用状态变更为 DOWNOFFLINEUNKNOWN 时,会自动发出告警。

  • Spring Boot Admin 内置了多种告警方式:

Skywalking 链路追踪

SkyWalking和Zipkin一样,也是一个开源的应用性能监控和分析系统,在国内使用较多。

主要功能

  • 全链路追踪: 支持全链路追踪,可以追踪分布式系统中请求的流程路径。
  • 性能指标收集: 除了追踪数据,还可以收集系统性能指标,比如:响应时间、吞吐量、错误率等。

  • 多种监控手段:通过语言探针和 Service Mesh 等手段,获得链路、日志、指标等监控数据
  • 多个语言探针:Java、.Net Core、PHP、NodeJS、Golang、LUA、Rust、C++ 等
    • 多语言支持: 提供多语言的客户端,包括:Java、Python、Go、.NET等。
  • 轻量级高性能:无需大数据组件,无需大量的硬件资源,且对应用实例的负载消耗极低
  • 模块化架构:数据传输、数据存储,注册发现等模块,可替换不同的基础设施实现
  • 端到端的监控:Vue、React 等前端,Java、.Net Core、PHP、NodeJS、Golang、Istio 等后端
  • 告警机制:内置 Webhooks 发送事件通知,支持通过 HTTP、gRPC、Slack 等方式
    • 告警与通知: 允许设置警报规则,当性能或指标达到预定的阈值时,可以触发告警通知。
  • 可视化界面:好用的监控后台,可支持自定义配置,或是集成你自己的

功能列表

整体架构

架构图

整个架构,分成上、下、左、右四部分:

  1. 【左】Agent:在应用中,收集(Trace、Log、Metrics 等)监控数据,使用 RPC、RESTful API、Kafka 等 Transport 传输方式,发送给 OAP 服务。
  2. 【下】OAP:首先 Receiver 接收 Agent 发送的监控数据,然后 Aggregator 进行聚合计算,之后存储到 Storage 外部存储器,最终提供给 GUI 查询数据。
  3. 【右】Storage:存储监控数据,支持 Elasticsearch、MySQL、TiDB、H2 等多种数据库。
  4. 【上】GUI:UI 可视化界面,提供监控数据的查询后台。

工作原理

  • 代理和收集器: 在应用程序中嵌入 SkyWalking 代理,它会捕获请求中的跨度数据,并将数据发送到 SkyWalking 收集器
  • 数据存储: 收集器将跨度数据存储在后端的存储系统中(通常是数据库或索引系统,用于存储、索引和检索跨度数据)。
  • 可视化界面: 存储的跨度数据可以通过可视化界面查询和展示。用户可以使用界面查看请求的路径、性能信息和指标图表。

搭建单机环境

参考:SkyWalking 9.X 极简入门(新版本)

搭建一个 SkyWalking 单机环境,步骤如下:

  1. 第一步,搭建一个 Elasticsearch 服务。
  2. 第二步,下载 SkyWalking 软件包。
  3. 第三步,搭建一个 SkyWalking OAP 服务。
  4. 第四步,启动一个 Spring Boot 应用,并配置 SkyWalking Agent 探针。
  5. 第五步,搭建一个 SkyWalking UI 服务。浏览器打开 http://127.0.0.1:8080 地址

SkyWalking 单机环境

UI 界面

① 访问下 http://127.0.0.1:8079/demo/echo 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

② 打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。

  • 可以看到 Spring Boot 应用的服务"demo-application",就是在环境变量 SW_AGENT_NAME 中所定义的。

服务(Service):表示对请求提供相同行为的一系列或一组工作负载。

  • 在使用 Agent 或 SDK 时,可以定义服务的名字。如果不定义的话,SkyWalking 将会使用你在平台(例如说 Istio)上定义的名字。

③ 点击 demo-application 这个服务名,可以看到该服务的【整体监控信息】。

  • 点击 [Instance] 选项卡,可以查到该服务的【实例列表】。

服务实例(Service Instance):上述的一组工作负载中的每一个工作负载称为一个实例。

  • 就像 Kubernetes 中的 pods 一样, 服务实例未必就是操作系统上的一个进程。但当在使用 Agent 时, 一个服务实例实际就是操作系统上的一个真实进程。

④ 点击 [Endpoint] 选项卡,可以查看到该服务的【端点列表】。

端点(Endpoint) :对于特定服务所接收的请求路径, 如 HTTP 的 URI 路径和 gRPC 服务的类名 + 方法签名。

  • 这里,可以看到 Spring Boot 应用的一个端点,为 API 接口 /demo/echo

⑤ 点击 [Topology] 选项卡,可以查看到该服务的【拓扑图】。

⑥ 点击 [Trace] 选项卡,可以查看到该服务的【链路】。

SkyWalking UI 界面 —— Trace

⑦ 点击 [Log] 选项卡,可以查看到该服务的【日志】。

IDEA 配置

SkyWalking Java Agent【IDEA】

考虑到偶尔我们需要在 IDE 中,也希望使用 SkyWalking Agent,可参考下图配置:

IDEA 界面

搭建 SkyWalking 集群环境

在生产环境下,一般推荐搭建 SkyWalking 集群环境。

  • 当然,如果公司比较抠门,也可以在生产环境下使用 SkyWalking 单机环境,毕竟 SkyWalking 挂了之后,不影响业务的正常运行。

搭建一个 SkyWalking 集群环境,步骤如下:

  1. 第一步,搭建一个 Elasticsearch 服务的集群
  2. 第二步,搭建一个注册中心的集群。目前 SkyWalking 支持 Zookeeper、Kubernetes、Consul、Nacos 作为注册中心。
  3. 第三步,搭建一个 SkyWalking OAP 服务的集群,同时参考 《SkyWalking 文档 —— 集群管理》 ,将 SkyWalking OAP 服务注册到注册中心上。
  4. 第四步,启动一个 Spring Boot 应用,并配置 SkyWalking Agent
    • 另外,在设置 SkyWaling Agent 的 SW_AGENT_COLLECTOR_BACKEND_SERVICES 地址时,需要设置多个 SkyWalking OAP 服务的地址数组。
  5. 第五步,搭建一个 SkyWalking UI 服务的集群,同时使用 Nginx 进行负载均衡。
    • 另外,在设置 SkyWalking UI 的 spring.cloud.discovery.client.simple.instances.oap-service 地址时,也需要设置多个 SkyWalking OAP 服务的地址数组。

Spring Boot 集成

参考:Spring Boot 链路追踪 SkyWalking 入门

Spring Cloud 集成

参考:Spring Cloud 链路追踪 SkyWalking

在 Spring Cloud 中使用 SkyWalking 作为链路追踪组件,实现服务调用的链路追踪、依赖的拓扑图、调用请求量的统计等等功能。

SpringMVC 示例

依赖、配置

  • 设置服务器的端口为 8079 ,避免和 SkyWalking UI 占用的 8080 冲突。

IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。

Run/Debug Configurations

简单测试

① 首先,使用浏览器,访问下 http://127.0.0.1:8079/user/get?id=1 地址,请求下 Spring Cloud 应用提供的 API。因为,我们要追踪下该链路。

② 然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:

SkyWalking UI 界面 —— 仪表盘

③ 之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 SpringMVC 小方块。如下图所示:SkyWalking UI 界面 —— 拓扑图

④ 再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

忽略部分 URL 的追踪

详见《芋道 Spring Boot 链路追踪 SkyWalking 入门》文章的「3. 忽略部分 URL 的追踪」小节。

Feign 示例

搭建一个 SkyWalking 对 Feign 的远程 HTTP 调用的链路追踪。该链路通过如下插件实现收集:

新建一个 labx-14-sc-skywalking-feign 项目作为消费者,使用 Feign 调用「2. SpringMVC 示例」labx-14-sc-skywalking-springmvc/user/get 接口。

项目结构

Spring Cloud Gateway 示例

示例代码对应仓库:

搭建一个 SkyWalking 对 Spring Cloud Gateway 的代理请求的链路追踪。该链路通过如下插件实现收集:

友情提示:因为 Spring Cloud Gateway 是基于 WebFlux 实现,必须搭配上 spring-webflux-5.x-plugin 插件一起使用,不能仅仅只使用 gateway-2.1.x-plugin 插件。

新建一个 labx-14-sc-skywalking-springcloudgateway 项目作为 API 网关,转发请求到后端服务。

项目结构

Zipkin

Zipkin是一款开源的分布式实时数据追踪系统,由Twitter开发并开源。

Zipkin 提供了可视化界面,用于查看请求的流程、跨度和时间线。

Spring Cloud Sleuth 分布式跟踪

分布式服务跟踪,日志收集工具包。封装了Dapper和log-based追踪以及Zipkin和HTrace操作,为SpringCloud应用实现了一种分布式追踪解决方案。

0%