SpringBoot - 构建监控体系01_使用 Actuator 组件实现及扩展系统监控

简介: SpringBoot - 构建监控体系01_使用 Actuator 组件实现及扩展系统监控

20210516092951966.png

Pre


这里我们将介绍 Spring Boot 中一个非常有特色的主题——系统监控。


系统监控是 Spring Boot 中引入的一项全新功能,它对应用程序运行状态的管理非常有效。而 Spring Boot Actuator 组件主要通过一系列 HTTP 端点提供的系统监控功能来实现系统监控。


因此,接下来我们将引入 Spring Boot Actuator 组件,介绍如何使用它进行系统监控,以及如何对 Actuator 端点进行扩展。


引入 Spring Boot Actuator 组件


在初始化 Spring Boot 系统监控功能之前,首先我们需要引入 Spring Boot Actuator 组件,具体操作为在 pom 中添加如下所示的 Maven 依赖:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>


Warning: 引入 Spring Boot Actuator 组件后,并不是所有的端点都对外暴露。

启动boot工程

20210530110914207.png


Exposing 2 endpoint(s) beneath base path '/actuator'

访问 http://localhost:8080/actuator 端点后,我们也会得到如下所示结果。


20210530110949138.png


这种结果就是 HATEOAS 风格的 HTTP 响应。如果我们想看到默认情况下看不到的所有端点,则需要在配置文件中添加如下所示的配置信息。

management:
  endpoints:
    web:
      exposure:
        include: "*"


重启应用后,

20210530111602460.png

我们就能获取到 Spring Boot Actuator 暴露的所有端点,如下代码所示:



20210530111644547.png


原生端点


根据端点所起到的作用,我们把 Spring Boot Actuator 提供的原生端点分为如下三类。


应用配置类: 主要用来获取应用程序中加载的应用配置、环境变量、自动化配置报告等配置类信息,它们与 Spring Boot 应用密切相关。


度量指标类: 主要用来获取应用程序运行过程中用于监控的度量指标,比如内存信息、线程池信息、HTTP 请求统计等。


操作控制类: 在原生端点中只提供了一个关闭应用的端点,即 /shutdown 端点。


根据 Spring Boot Actuator 默认提供的端点列表,我们将部分常见端点的类型、路径和描述梳理在如下表格中,仅供参考。

20210530111829494.png


应用更详细的健康状态


通过访问上表中的各个端点,我们就可以获取自己感兴趣的监控信息了。例如访问了http://localhost:8080/actuator/health端点,我们就可以得到应用的 基本状态。

20210530170801333.png

此时,我们看到这个健康状态信息非常简单。

那有没有什么办法可以获取更详细的状态信息呢? 我们只需要在配置文件中添加如下所示的配置项即可。

management: 
  endpoint:
    health:
      show-details: always

2021053017124994.png


20210530171346447.png


如何在现有的监控端点上添加定制化功能


如果 Spring Boot Actuator 默认提供的端点信息不能满足业务需求,我们可以对其进行修改和扩展。此时,常见实现方案有两种,一种是扩展现有的监控端点,另一种是自定义新的监控端点。 后面会讲这一部分,我们先来关注如何在现有的监控端点上添加定制化功能。


扩展 Actuator 端点


Spring Boot 默认暴露了日常开发中最常见的两个端点:Info 端点和 Health 端点。接下来,我们讨论下如何对这两个端点进行扩展。


扩展 Info端点 (InfoContributor )


Info 端点用于暴露 Spring Boot 应用的自身信息。在 Spring Boot 内部,它把这部分工作委托给了一系列 InfoContributor 对象,而 Info 端点会暴露所有 InfoContributor 对象所收集的各种信息。


在Spring Boot 中包含了很多自动配置的 InfoContributor 对象,常见的 InfoContributor 及其描述如下表所示:



20210530171656980.png

以上表中的 EnvironmentInfoContributor 为例,通过在配置文件中添加格式以“info”作为前缀的配置段,我们就可以定义 Info 端点暴露的数据。添加完成后,我们将看到所有在“info”配置段下的属性都将被自动暴露。


方式一: 配置文件


比如可以将如下所示配置信息添加到配置文件 application.yml 中:

info:
  app:
      encoding: UTF-8
      java:
          source: 1.8.0_31
          target: 1.8.0_31


现在访问 Info 端点, http://localhost:8080/actuator/info 我们就能得到如下的 Environment 信息。

20210530172103202.png


同时,我们还可以在服务构建时扩展 Info 属性,而不是硬编码这些值。假设使用 Maven,我们就可以按照如下所示的配置重写前面的示例并得到同样的效果。

20210530172841564.png


20210530172912743.png


方式二:实现 InfoContributor 接口 重写contribute() 方法


很多时候,Spring Boot 自身提供的 Info 端点并不能满足我们的业务需求,这就需要我们编写一个自定义的 InfoContributor 对象。


方法也很简单,我们直接实现 InfoContributor 接口的 contribute() 方法即可。例如,我们希望在 Info 端点中暴露该应用的构建时间,就可以采用如下所示的代码进行操作。

package com.artisan.admin;
import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.Date;
/**
 * @author 小工匠
 * @version 1.0
 * @description: TODO
 * @date 2021/5/30 17:30
 * @mark: show me the code , change the world
 */
@Component
public class ArtisanInfoContributor implements InfoContributor {
    @Override
    public void contribute(Info.Builder builder) {
        builder.withDetail("build", Collections.singletonMap("timestamp", new Date()));
    }
}

重新构建应用并访问 Info 端口后,我们就能获取如下所示信息。


20210530173303264.png


这里我们可以看到,ArtisanInfoContributor 为 Info 端口新增了时间属性。


扩展 Health 端点


Health 端点用于检查正在运行的应用程序健康状态,而健康状态信息由 HealthIndicator 对象从 Spring 的 ApplicationContext 中获取。


和 Info 端点一样,Spring Boot 内部也提供了一系列 HealthIndicator 对象供我们实现定制化。在默认情况下,HealthAggregator 会根据 HealthIndicator 的有序列表对每个状态进行排序,从而得到最终的系统状态。


常见的 HealthIndicator


常见的 HealthIndicator 如下表所示:


20210530173422231.png


Health 端点信息的丰富程度取决于当下应用程序所处的环境,而一个真实的 Health 端点信息如下代码所示:

{
     "status":"UP",
     "components":{
         "db":{
             "status":"UP",
             "details":{
                 "database":"MySQL",
                 "result":1,
                 "validationQuery":"/* ping */ SELECT 1"
             }
         },
         "diskSpace":{
             "status":"UP",
             "details":{
                 "total":201649549312,
                 "free":3491287040,
                 "threshold":10485760
             }
         },
         "ping":{
             "status":"UP"
         }
  }
}


通过以上这些信息,我们就可以判断该环境中是否包含了 MySQL 数据库。


实现HealthIndicator 接口 重写 health方法


现在,我们还想在 Health 端点中暴露 customer-service 当前运行时状态。


为了进一步明确该服务的状态,我们可以自定义一个 CustomerServiceHealthIndicator 端点专门展示 应用 的状态信息,CustomerServiceHealthIndicator 的定义如下所示:

@Component
public class CustomerServiceHealthIndicator implements 
  HealthIndicator {
    @Override
    public Health health() {
        try {
        URL url = new  URL("http://localhost:8083/health/");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
              int statusCode = conn.getResponseCode();
              if (statusCode >= 200 && statusCode < 300) {
                   return Health.up().build();
              } else {
                return Health.down().withDetail("HTTP Status Code", statusCode).build();
            }
        } catch (IOException e) {
            return Health.down(e).build();
        }
    }
}

我们需要提供 health() 方法的具体实现并返回一个 Health 结果。该 Health 结果应该包括一个状态,并且可以根据需要添加任何细节信息。


以上代码中,我们使用了一种简单且直接的方式判断配置中心服务“customerservice”是否正在运行。然后我们构建一个 HTTP 请求,并根据 HTTP 响应得出了健康诊断的结论。


如果 HTTP 响应的状态码处于 200~300 之间,我们认为该服务正在运行,此时,Health.up().build() 方法就会返回一种 Up 响应,如下代码所示:

{
    "status": "UP",
    "details": {
        "customerservice":{
            "status": "UP"
        }
   }
}

如果状态码不处于这个区间(例如返回 404,代表服务不可用),Health.down().withDetail().build() 方法就会返回一个 Down 响应,并给出具体的状态码,如下代码所示:

{
    "status": "DOWN",
    "details": {
        "customerservice":{
            "status": "DOWN",
            "details": {
                "HTTP Status Code": "404"
            }
        },
    }
}

如果 HTTP 请求直接抛出了异常,Health.down().build() 方法同样会返回一个 Down 响应,并返回异常信息,效果如下代码所示:

{
    "status": "DOWN",
    "details": {
        "customerservice":{
            "status": "DOWN",
            "details": {
                "error": "java.net.ConnectException: Connection refused: connect"
            }
        },
    }
}


显然,通过扩展 Health 端点为我们实时监控系统中各个服务的正常运行状态提供了很好的支持,我们也可以根据需要构建一系列有用的 HealthIndicator 实现类,并添加报警等监控手段。


小结


Spring Boot 内置的 Actuator 组件使得开发人员在管理应用程序运行的状态有了更加直接且高效的手段。


我们引入了 Actuator 组件并介绍了该组件提供的一系列核心端点,同时重点分析了 Info 和 Health 这两个基础端点,并给出了对它们进行扩展的系统方法。


系统监控的一大目标是收集和分析系统运行时的度量指标,并基于这些指标判断当前的运行时状态。

相关文章
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
48 4
|
1月前
|
Java API 数据库
如何使用Spring Boot构建RESTful API,以在线图书管理系统为例
【10月更文挑战第9天】本文介绍了如何使用Spring Boot构建RESTful API,以在线图书管理系统为例,从项目搭建、实体类定义、数据访问层创建、业务逻辑处理到RESTful API的实现,详细展示了每个步骤。通过Spring Boot的简洁配置和强大功能,开发者可以高效地开发出功能完备、易于维护的Web应用。
60 3
|
23天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
97 62
|
15天前
|
Java
SpringBoot构建Bean(RedisConfig + RestTemplateConfig)
SpringBoot构建Bean(RedisConfig + RestTemplateConfig)
37 2
|
21天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
40 2
|
24天前
|
Java 开发者 Spring
精通SpringBoot:16个扩展接口精讲
【10月更文挑战第16天】 SpringBoot以其简化的配置和强大的扩展性,成为了Java开发者的首选框架之一。SpringBoot提供了一系列的扩展接口,使得开发者能够灵活地定制和扩展应用的行为。掌握这些扩展接口,能够帮助我们写出更加优雅和高效的代码。本文将详细介绍16个SpringBoot的扩展接口,并探讨它们在实际开发中的应用。
39 1
|
29天前
|
自然语言处理 Java API
Spring Boot 接入大模型实战:通义千问赋能智能应用快速构建
【10月更文挑战第23天】在人工智能(AI)技术飞速发展的今天,大模型如通义千问(阿里云推出的生成式对话引擎)等已成为推动智能应用创新的重要力量。然而,对于许多开发者而言,如何高效、便捷地接入这些大模型并构建出功能丰富的智能应用仍是一个挑战。
112 6
|
1月前
|
文字识别 安全 Java
SpringBoot3.x和OCR构建车牌识别系统
本文介绍了一个基于Java SpringBoot3.x框架的车牌识别系统,详细阐述了系统的设计目标、需求分析及其实现过程。利用Tesseract OCR库和OpenCV库,实现了车牌图片的识别与处理,确保系统的高准确性和稳定性。文中还提供了具体的代码示例,展示了如何构建和优化车牌识别服务,以及如何处理特殊和异常车牌。通过实际应用案例,帮助读者理解和应用这一解决方案。
|
15天前
|
XML 存储 Java
SpringBoot集成Flowable:构建强大的工作流引擎
在企业级应用开发中,工作流管理是核心功能之一。Flowable是一个开源的工作流引擎,它提供了BPMN 2.0规范的实现,并且与SpringBoot框架完美集成。本文将探讨如何使用SpringBoot和Flowable构建一个强大的工作流引擎,并分享一些实践技巧。
40 0
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第8天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建并配置 Spring Boot 项目,实现后端 API 和安全配置。接着,使用 Ant Design Pro Vue 脚手架创建前端项目,配置动态路由和菜单,并创建相应的页面组件。最后,通过具体实践心得,分享了版本兼容性、安全性、性能调优等注意事项,帮助读者快速搭建高效且易维护的应用框架。
42 3

热门文章

最新文章