如何实现自定义度量指标和Actuator端点?

本文我们将介绍Spring Boot中一个非常有特色的主题,这个主题就是系统监控。系统监控是Spring Boot中引入的一项全新功能,对于管理应用程序运行时状态非常有用。Spring Boot Actuator组件是承载系统监控功能的组件,通过一系列HTTP端点提供系统监控功能。在本文中,我们将先引入这一组件,并介绍如何使用和扩展Actuator端点。

Actuator组件

初始化Spring Boot系统监控功能需要引入Spring Boot Actuator组件,我们在pom中添加如下Maven依赖:

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

请注意,引入Spring Boot Actuator组件之后,并不是所有端点都是对外暴露的。例如,当我们启动customer-service时,在启动日志里会发现如下日志:

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

当访问http://localhost:8080/actuator端点时会得到如下结果:

{
    "_links":{
        "self":{
            "href":"http://localhost:8080/actuator",
            "templated":false
        },
        "health-path":{
            "href":"http://localhost:8080/actuator/health/{*path}",
            "templated":true
        },
        "health":{
            "href":"http://localhost:8080/actuator/health",
            "templated":false
        },
        "info":{
            "href":"http://localhost:8080/actuator/info",
            "templated":false
        }
    }
}

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

management:

  endpoints:

    web:

      exposure:

        include: "*"  

重启应用,这时候就能获取Spring Boot Actuator所暴露的所有端点,如下所示:

{
    "_links":{
        "self":{
            "href":"http://localhost:8080/actuator",
            "templated":false
        },
        "beans":{
            "href":"http://localhost:8080/actuator/beans",
            "templated":false
        },
        "health":{
            "href":"http://localhost:8080/actuator/health",
            "templated":false
        },
        "health-path":{
            "href":"http://localhost:8080/actuator/health/{*path}",
            "templated":true
        },
        "info":{
            "href":"http://localhost:8080/actuator/info",
            "templated":false
        },
        "conditions":{
            "href":"http://localhost:8080/actuator/conditions",
            "templated":false
        },
        "configprops":{
            "href":"http://localhost:8080/actuator/configprops",
            "templated":false
        },
        "env":{
            "href":"http://localhost:8080/actuator/env",
            "templated":false
        },
        "env-toMatch":{
            "href":"http://localhost:8080/actuator/env/{toMatch}",
            "templated":true
        },
        "loggers":{
            "href":"http://localhost:8080/actuator/loggers",
            "templated":false
        },
        "loggers-name":{
            "href":"http://localhost:8080/actuator/loggers/{name}",
            "templated":true
        },
        "heapdump":{
            "href":"http://localhost:8080/actuator/heapdump",
            "templated":false
        },
        "threaddump":{
            "href":"http://localhost:8080/actuator/threaddump",
            "templated":false
        },
        "metrics-requiredMetricName":{
            "href":"http://localhost:8080/actuator/metrics/{requiredMetricName}",
            "templated":true
        },
        "metrics":{
            "href":"http://localhost:8080/actuator/metrics",
            "templated":false
        },
        "scheduledtasks":{
            "href":"http://localhost:8080/actuator/scheduledtasks",
            "templated":false
        },
        "mappings":{
            "href":"http://localhost:8080/actuator/mappings",
            "templated":false
        }
    }
}

根据端点所起到的作用,我们可以把Spring Boot Actuator提供的这些原生端点分为如下三大类:

  1. 应用配置类:获取应用程序中加载的应用配置、环境变量、自动化配置报告等与Spring Boot应用密切相关的配置类信息。
  2. 度量指标类:获取应用程序运行过程中用于监控的度量指标,比如内存信息、线程池信息、HTTP请求统计等。
  3. 操作控制类:在原生端点中,只提供了一个用来关闭应用的端点,即/shutdown端点。

Spring Boot Actuator默认提供的端点列表中,部分常见端点的类型、路径和描述参考下表:

类型

路径

描述

应用配置类

/beans

该端点用来获取应用程序中所创建的所有JavaBean信息

/env

该端点用来获取应用程序中所有可用的环境属性,包括环境变量、JVM属性、应用配置信息等。

/info

该端点用来返回一些应用自定义的信息。开发人员可以对其进行扩展,本课时后续会有详细案例。

/mappings

该端点用来返回所有Controller中RequestMapping所表示的映射信息。

度量指标类

/metrics

该端点用来返回当前应用程序的各类重要度量指标,如内存信息、线程信息、垃圾回收信息等。

/threaddump

该端点用来暴露应用程序运行中的线程信息。

/health

该端点用来获取应用的各类健康指标信息,这些指标信息由 HealthIndicator 的实现类提供。本课时后续同样会有扩展HealthIndicator的代码案例。

/trace

该端点用来返回基本的HTTP跟踪信息。

操作控制类

/shutdown

该端点用来关闭应用程序,要求 endpoints.shutdown.enabled 设置为 true。

我们可以访问上表中的各个端点以获取自己感兴趣的监控信息,例如访问actuator/health端点可以得到当前account-service的基本状态,如下所示:

{
     "status":"UP"
}

可以看到这个健康状态信息非常简单,有没有办法获取更加详细的信息呢?办法很简单,就是在配置文件中添加如下所示的配置项:

management:

  endpoint:

    health:

      show-details: always

上述配置项指定了针对health这个端点需要显示它的详细信息。这时候,如果我们重启Spring Boot应用程序,并重新访问actuator/health端点,那么就可以获取如下所示的详细信息:

{
    "status":"UP",
    "components":{
        "diskSpace":{
            "status":"UP",
            "details":{
                "total":201649549312,
                "free":3434250240,
                "threshold":10485760
            }
        },
        "ping":{
            "status":"UP"
        }
    }
}

如果Spring Boot Actuator默认提供的端点信息不能满足需求,我们还可以对其进行修改和扩展。常见实现方案有两种,一种是扩展现有的监控端点,另一种是自定义新的监控端点。本课程会对这两种方案都进行详细介绍,今天我们先来关注如何在现有的监控端点上添加定制化功能。

扩展Actuator端点案例分析

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

扩展Info端点

Info端点用于暴露Spring Boot应用的自身信息。在Spring Boot内部,它把这部分工作委托给了一系列InfoContributor对象。Info端点会暴露所有InfoContributor 对象所收集的各种信息,Spring Boot包含很多自动配置的InfoContributor对象,常见的InfoContributor及其描述如下表所示。

InfoContributor名称

描述

EnvironmentInfoContributor

暴露Environment中key为info的所有key

GitInfoContributor

暴露git信息,如果存在git.properties文件

BuildInfoContributor

暴露构建信息,如果存在META-INF/build-info.properties文件

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

info:

  app:

    encoding: UTF-8

    java:

        source: 1.8.0_31

        target: 1.8.0_31

现在访问Info端点,就能得到如下的Environment信息:

{
    "app":{
        "encoding":"UTF-8",
        "java":{
            "source":"1.8.0_31",
            "target":"1.8.0_31"
        }
    }
}

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

info:

  app:

    encoding: @project.build.sourceEncoding@

    java:

      source: @java.version@

      target: @java.version@

更多的时候Spring Boot自身提供的Info端点并不能满足我们的业务需求,这就需要编写自定义的InfoContributor对象。方法也很简单,直接实现InfoContributor接口的contribute()方法即可。例如,我们希望在Info端点中能够暴露该应用的构建时间,就可以采用如下所示的代码示例:

@Component

public class CustomBuildInfoContributor implements InfoContributor {

@Override

public void contribute(Builder builder) {

builder.withDetail("build",

Collections.singletonMap("timestamp", new Date()));

}

}

重新构建应用并访问Info端口,将获取如下信息:

{
    "app":{
        "encoding":"UTF-8",
        "java":{
            "source":"1.8.0_31",
            "target":"1.8.0_31"
        }
    },
    "build":{
        "timestamp":1604307503710
    }
}

可以看到CustomBuildInfoContributor为Info端口新增了构建时间属性。

扩展Health端点

Health端点用于检查正在运行的应用程序健康状态。健康状态信息是由HealthIndicator对象从Spring的 ApplicationContext中进行获取。和Info端点一样,Spring Boot内部也提供了一系列HealthIndicator对象,而我们也可以实现定制化。默认情况下,最终的系统状态是由 HealthAggregator根据HealthIndicator的有序列表对每个状态进行排序,常见的HealthIndicator如下表所示:

HealthIndicator名称

描述

CassandraHealthIndicator

检查Cassandra数据库是否启动。

DiskSpaceHealthIndicator

检查磁盘空间是否足够。

DataSourceHealthIndicator

检查是否可以获得连接DataSource。

ElasticsearchHealthIndicator

检查Elasticsearch集群是否启动。

InfluxDbHealthIndicator

检查InfluxDB服务器是否启动。

JmsHealthIndicator

检查JMS代理是否启动。

MailHealthIndicator

检查邮件服务器是否启动。

MongoHealthIndicator

检查Mongo数据库是否启动。

Neo4jHealthIndicator

检查Neo4j服务器是否启动。

RabbitHealthIndicator

检查RabbitMQ服务器是否启动。

RedisHealthIndicator

检查Redis服务器是否启动。

SolrHealthIndicator

检查Solr服务器是否已启动。

Health端点信息的丰富程度取决于当下应用程序所处的环境,一个真实的Health端点信息如下所示。通过这些信息,我们可以判断该环境中包含了MySQL数据库:

{
    "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"
        }

}

}

现在,我们想在Health端点中暴露customer-service的当前运行时状态。为了进一步明确该服务的状态,我们可以自定义一个CustomerServiceHealthIndicator端点用来专门展示customer-service的状态信息。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代表服务不可用)就返回一个Down响应并给出具体的状态码,如下所示。

{

    "status": "DOWN",

    "details": {

        "customerservice":{

            "status": "DOWN",

            "details": {

                "HTTP Status Code": "404"

            }

        },

        …

    }

}

如果HTTP请求直接抛出了异常,我们同样返回一个Down响应,同时把异常信息一起返回,效果如下所示。

{

    "status": "DOWN",

    "details": {

        "customerservice":{

            "status": "DOWN",

            "details": {

                "error": "java.net.ConnectException: Connection refused: connect"

            }

        },

        …

    }

}

 

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

自定义Actuator端点案例分析

在日常开发过程中,有时候扩展现有端点并不一定能够满足需求,自定义Spring Boot Actuator监控端点是更灵活的方法。

现在,假设我们需要提供一个监控端点以获取当前系统的用户信息和计算机名称,我们就可以实现一个独立的MySystemEndPoint,代码如下所示:

@Configuration

@Endpoint(id = "mysystem", enableByDefault=true)

public class MySystemEndpoint {

   @ReadOperation

    public Map<String, Object> getMySystemInfo() {

        Map<String,Object> result= new HashMap<>();

        Map<String, String> map = System.getenv();

        result.put("username",map.get("USERNAME"));

        result.put("computername",map.get("COMPUTERNAME"));

        return result;

    }

}

可看到,MySystemEndpoint通过系统环境变量获取所需监控信息。注意到这里引入了一个新的注解@Endpoint,该注解定义如下:

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface Endpoint {

//端点Id

String id() default "";

//是否默认启动标志位

boolean enableByDefault() default true;

}

@Endpoint注解用于设置端点Id以及是否默认启动的标志位。在案例中,我们分别指定id为“mysystem”,enableByDefault标志为true。事实上,在Actuator中存在一批类似@Endpoint的端点注解。其中被@Endpoint注解的端点可通过JMX和Web应用程序访问。对应的@JmxEndpoint只能通过JMX访问,而@WebEndpoint只能通过Web访问。

然后,我们在示例代码中还看到了一个@ReadOperation注解,该注解作用于方法,用于标识读取数据操作。在Actuator中,除了@ReadOperation注解之外,还有@WriteOperation和@DeleteOperation注解分别对应写入和删除操作。

现在访问http://localhost:8080/actuator/mysystem就能获取如下监控信息。

{
     "computername":"LAPTOP-EQB59J5P",
     "username":"user"
}

有时候,我们需要对某一个端点传递参数以获取特定的度量信息。在Actuator中,专门提供了一个@Selector注解来标识输入参数,示例代码如下所示:

@Configuration

@Endpoint(id = "account", enableByDefault = true)

public class AccountEndpoint {

@Autowired

private AccountRepository accountRepository;

@ReadOperation

public Map<String, Object> getMySystemInfo(@Selector String arg0) {

Map<String, Object> result = new HashMap<>();

result.put(accountName, accountRepository.findAccountByAccountName(arg0));

return result;

}

}

这段代码的逻辑非常简单,就是根据传入的accountName来获取用户账户信息。请注意,通过@Selector注解,这个时候我们就可以使用http://localhost:8080/actuator/ account/account1这样的端口地址来触发度量操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/599459.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[蓝桥杯]真题讲解:班级活动(贪心)

[蓝桥杯]真题讲解&#xff1a;班级活动&#xff08;贪心&#xff09; 一、视频讲解二、正解代码1、C2、python33、Java 一、视频讲解 [蓝桥杯]真题讲解&#xff1a;班级活动&#xff08;贪心&#xff09; 二、正解代码 1、C #include<bits/stdc.h> using namespace st…

28.leetcode---前K个高频单词(Java版)

题目链接: https://leetcode.cn/problems/top-k-frequent-words/description/ 题解: 代码: 测试:

Offline:IQL

ICLR 2022 Poster Intro 部分离线强化学习的对价值函数采用的是最小化均方bellman误差。而其中误差源自单步的TD误差。TD误差中对target Q的计算需要选取一个max的动作&#xff0c;这就容易导致采取了OOD的数据。因此&#xff0c;IQL取消max,&#xff0c;通过一个期望回归算子…

QT creator qt6.0 使用msvc2019 64bit编译报错

qt creator qt6.0报错&#xff1a; D:\Qt6\6.3.0\msvc2019_64\include\QtCore\qglobal.h:123: error: C1189: #error: "Qt requires a C17 compiler, and a suitable value for __cplusplus. On MSVC, you must pass the /Zc:__cplusplus option to the compiler."…

PXE批量网络装机和Kickstart无人值守安装

一、PXE定义 PXE&#xff08;preboot execute environment&#xff09;:用于通过网络来引导系统的标准&#xff0c;工作在Client/Server模式&#xff08;也称为CS模式&#xff09;&#xff0c;允许客户机通过网络从远程服务器上下载引导镜像&#xff0c;并加载安装文件或整个操…

劝退计算机?CS再过几年会没落!?

事实上&#xff0c;未来计算机不仅不会没落&#xff0c;国家还会大力发展 只不过大家认为的计算机就是什么Java web&#xff0c;真正的计算机行业是老美那样的&#xff0c;涉及到方方面面&#xff0c;比如&#xff1a; web&#xff0c;图形学&#xff0c;Linux系统开发&#…

酷得智能电子方案 早教学习机

早教学习机是用户友好的&#xff0c;易于操作&#xff0c;同时要确保内容的科学性和适宜性&#xff0c;以促进儿童的健康成长和智力发展。 通常包括以下几个方面&#xff1a; 1.年龄分级内容&#xff1a;软件会根据儿童的不同年龄段提供相应的教育内容&#xff0c;从新生儿到…

renren-fast开源快速开发代码生成器

简介 renrenfast框架介绍 renren-fast是一个轻量级的Spring Boot快速开发平台&#xff0c;能快速开发项目并交付.完善的XSS防范及脚本过滤&#xff0c;彻底杜绝XSS攻击实现前后端分离&#xff0c;通过token进行数据交互 使用流程 项目地址 https://gitee.com/renrenio/ren…

鸿蒙 DevEcoStudio:组件实例(页面及组件生命周期函数)

【使用onPageshow等生命周期函数】 在entry/src/main/ets/pages路径下创建Page1.ets: import router from ohos.router Entry Component struct Page1 {State message: string Hello WorldState show: booleantrueaboutToAppear(){console.log(Page1组件创建实例)}aboutToDisa…

夏天旅行,就认准这五款随身WiFi!准没错!2024随身wifi靠谱品牌推荐,高性价比高口碑随身wifi推荐

过了五一&#xff0c;气温逐渐上升&#xff0c;又到了最适合旅行的季节。这个时候一款趁手的随身WiFi当然是必不可少的&#xff01;不但能解决出行时信号差的烦恼&#xff0c;还可以解决流量不够用的问题。那么&#xff0c;都有哪些随身WiFi在夏季出行时最值得选择呢&#xff1…

docker容器安装sqlserver

docker容器安装sqlserver 搜索SQL Server镜像下载SQL Server镜像创建容器 搜索SQL Server镜像 docker search mssql-server下载SQL Server镜像 docker pull microsoft/mssql-server-linux创建容器 docker run -e ACCEPT_EULAY -e SA_PASSWORD<YourStrong!Passw0rd> -…

庐山西海服务区:从高速服务区到旅游热点的华丽转身

五一假期期间&#xff0c;庐山西海服务区以其独特的魅力吸引了众多游客的目光。曾经只是一个供汽车加油和休息的普通服务区&#xff0c;如今却焕发出了绚丽的光彩&#xff0c;成为了周边地区备受瞩目的旅游热点。庐山西海服务区的转型&#xff0c;不仅为游客带来了丰富多样的娱…

leetCode78. 子集

leetCode78. 子集 思路一&#xff1a;迭代法 代码 class Solution { public:vector<vector<int>> subsets(vector<int>& nums) {vector<vector<int>> res;int n nums.size();for(int i 0; i < 1 << n; i) // 1 << n 2^n{…

记录一个练手的js逆向password

很明显 请求加密了password 全局搜索 有个加密函数(搜不到的可以搜临近的其他的关键字 或者url参数) 搜索的时候一定要仔细分析 我就没有仔细分析 我搞了好久 又是xhr又是hook的(还没hook到) 我当时也是疏忽了 我寻思这个也不是js文件 直到后来 我怎么也找不到 我就猜想 不…

【一刷《剑指Offer》】面试题 16:反转链表

力扣对应题目链接&#xff1a;206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 牛客对应题目链接&#xff1a;反转链表_牛客题霸_牛客网 (nowcoder.com) 核心考点 &#xff1a;链表操作&#xff0c;思维缜密程度。 一、《剑指 Offer》内容 二、分析题目 解题思路&#…

动态规划——路径问题:LCR 166.珠宝的最高价值

文章目录 题目描述算法原理1.状态表示&#xff08;题目经验&#xff09;2.状态转移方程3.初始化4.填表顺序5.返回值 代码实现CJava 题目描述 题目链接&#xff1a;LCR 166.珠宝的最高价值 算法原理 1.状态表示&#xff08;题目经验&#xff09; 对于这种路径类的问题&…

pytest教程-39-钩子函数-pytest_runtest_setup

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_runtest_protocol钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_runtest_setup钩子函数的使用方法。 pytest_runtest_setup 钩子函数在每个测试用例的 setup 阶段被调用。这…

43.WEB渗透测试-信息收集-域名、指纹收集(5)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;42.WEB渗透测试-信息收集-域名、指纹收集&#xff08;4&#xff09; web-架构资产收集&a…

手动配置dns后网速变慢

之前因为自动的dns能上qq但打不开网页&#xff0c;就手动设置了一个&#xff0c;结果近些天时不时出现网页图片加载慢的问题&#xff0c;影响到我看美女图片了&#xff0c;是可忍熟不可忍 测了下网速&#xff0c;很快&#xff0c;下载上传都是三位数的&#xff0c;那显然不是网…

文本转图表的AI工具-Chart-GPT

Chart-GPT Chart-GPT一款基于 GPT 实现的开源工具&#xff0c;可在几秒内&#xff0c;将文本快速转换为各种图表。用户只需在输入字段中输入数据说明和所需的图表类型&#xff0c;Chart-GPT的后台生成器即可建出多种类型的图表&#xff0c;包括条形图、折线图、组合图、散点图、…
最新文章