Spring Boot Actuator的端点都怎么用?咱用事实说话!

程序新视界

共 12171字,需浏览 25分钟

 ·

2021-07-18 18:46

前言

在微服务系统架构中,服务的监控是必不可少的。目前大多数微服务应用又是基于Spring Cloud系列,也可以说是基于Spring Boot系列的。此时使用Spring Boot Actuator来进行微服务的监控,不仅功能全面,而且非常方便。

在上篇文章《Spring Boot Actuator集成,难的是灵活运用!》中我们已经介绍了如何将Actuator集成到Spring Boot项目中,并且介绍了如何自定义Endpoint(端点)。有朋友留言说不够深入,那么,本篇文章呢,我们将介绍Actuator原生端点的功能及基本使用场景。

Endpoints 介绍

Actuator中所谓的 Endpoints (翻译为端点)提供了外部来与应用程序进行访问和交互的功能。比如说/health端点提供了应用健康情况的信息,metrics 端点提供了应用程序的指标(JVM 内存使用、系统CPU使用等)信息。

Actuator原生的端点可分为三大类:

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

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

  • 操作控制类:提供了对应用的关闭等操作类功能。

不同版本的Actuator提供的原生端点有所出入,在使用的过程中最好以所使用版本的官方文档为准。同时,每个原生的端点都可以通过配置来单独的禁用或启用。

而在Actuator 2.x 中默认端点增加了/actuator前缀,同时默认只暴露的两个端点为/actuator/health和 /actuator/info。关于端点暴露的配置,可参考前一篇文章。下面基于Spring Boot 2.2.2.RELEASE版本来重点讲解每个端点的功能和应用场景。

actuator端点

Actuator 2.x新增的默认端点,用于展示目前应用中暴露出来的端点汇总,你可以理解为可用端点的目录。

访问URL:http://localhost:8080/actuator ,对应展示结果如下图:

上述只展示了一部分的端点,返回结果为JSON,这里采用了浏览器的JSON插件JSON-Handler进行了格式美化。通过actuator可以直观的看出目前开放了哪些端点,以及这些端点的名称和请求路径。

下面我们就按照显示actuator端点展示的列表逐一介绍。

auditevents端点

auditevents端点用于显示应用暴露的审计事件 (比如认证进入、订单失败),即使我们打开了所有端点,默认情况下也是看不到这个端点的。因为使用它的前提是需要在Spring容器中存在一个类型为AuditEventRepository的Bean的。

查看了网络上大多数教程,基本上都是介绍了auditevents端点功能,而未展示具体实例。笔者经过多方尝试,终于给大家写了一个案例出来。

首先涉及到权限认证,需要先引入spring-boot-starter-security依赖:

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

单纯添加这个依赖还是不够的,还需要加入security的配置,不然AuthorizationAuditListener,AuthenticationAuditListener 监听什么事件呢? 因此,我们加入如下代码:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.inMemoryAuthentication()
.withUser("admin")
.password(bcryptPasswordEncoder().encode("admin"))
.roles("admin");
}

@Bean
public PasswordEncoder bcryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}

这里采用了security默认的登录界面和权限控制,也就是说所有的访问都需要进行登录。而登录的用户名和密码均为admin。

另外,前面提到需要用到AuditEventRepository的Bean,这里初始化一个对应的Bean:

@Configuration
public class AuditEventConfig {

@Bean
public InMemoryAuditEventRepository repository(){
return new InMemoryAuditEventRepository();
}
}

InMemoryAuditEventRepository是AuditEventRepository接口的唯一实现类。

重启项目,auditevents端点便可用了。访问http://localhost:8080/actuator ,此时会跳转到Security提供的登录页面:

输入代码中指定的用户名和密码,登录成功,跳转到/actuator页面:

可以看到auditevents端点已经成功显示出来了。新开页面访问http://localhost:8080/actuator/auditevents ,展示内容如下:

可以看到已经记录下了权限相关的事件,其中第一次事件是我们直接访问actuator端点时,由于之前为做权限认真,所以事件类型为"AUTHORIZATION_FAILURE",也就是认证失败。此时跳转到登录页面,然后在登录页面输入用户名和密码,登录成功,对应的事件为"AUTHENTICATION_SUCCESS"。

也就是说auditevents记录了用户认证登录系统相关的事件信息,包括时间戳、认证用户、事件类型、访问地址、sessionId等。

示例源码地址:https://github.com/secbr/springboot-all/tree/master/springboot-actuator-auditevents 。

beans端点

/beans端点会返回Spring容器中所有bean的别名、类型、是否单例、依赖等信息。

访问路径为http://localhost:8080/actuator/beans,范围结果如下:

这个端点会展示目前Spring容器中初始化的所有Bean,试想一下,如果你配置了一个Bean,但不确定是否成功实例化,是不是就可以通过这个端口查询一下呢?

我们在项目中定义一个TestController,并注入一个UserService:

@Controller
public class TestController {

@Resource
private UserService userService;
}

重新启动并访问该端点,会看到如下信息: 

可以看到TestController被实例化了,而且依赖于UserService。

caches端点

caches端点主要用于暴露应用程序中的缓冲。这里以Spring Boot提供的Cache组件来展示一下实例。

在项目中集成spring-boot-starter-cache,引入依赖:

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

然后在启动类上添加@EnableCaching,开启缓存功能。

定义一个CacheController,对其方法queryAll使用缓存机制:

@RestController
public class CacheController {

@RequestMapping("/queryAll")
@Cacheable(value = "queryAll")
public Map<String, String> queryAll() {
Map<String, String> map = new HashMap<>();
map.put("1", "Tom");
map.put("2", "Steven");
return map;
}
}

这里使用@Cacheable注解来实现缓存功能,缓存的key为queryAll。此时,访问http://localhost:8080/actuator/caches ,会展示缓存的根内容,但里面并没有缓存。

访问一下http://localhost:8080/queryAll ,也就是触发一下缓存内容的生成。此时再访问上面的链接,便可以看到应用程序中的缓存信息了:

可以看到,返回的内容不仅展示了应用程序的缓存管理器,同时也展示了缓存的Key和缓存数据存储类型信息。

caches-cache端点

caches-cache端点是对上面caches端点的扩展,caches端点展示的所有的缓存信息。如果想直接看出具体的一个缓存信息,则可以使用caches-cache端点。

访问的URL为:http://localhost:8080/actuator/caches/{cache},其中大括号内的值可以替换为缓存的key。

http://localhost:8080/actuator/caches/queryAll

将上面的占位符换成queryAll(缓存的key),执行结果如下:

可以看出,只查询除了指定的缓存信息,包括缓存管理器、缓存名称(key),缓存的存储类型。

health端点

health端点用来检查应用的运行状态,最高频使用的一个端点。检查应用实例的运行状态以及应用不”健康“的原因,比如数据库连接、磁盘空间不够等。

访问地址:http://localhost:8080/actuator/health

展示结果:

{
"status": "UP"
}

上面的实例过于简单,在项目中把数据库给集成进去:

<!--数据库连接相关-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

然后在application配置文件中进行配置:

spring:
datasource:
url: jdbc:mysql://xxx:3333/xxx?characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver

同时,我们要在application配置文件中配置一下management.endpoint.health.show-details的值。该属性有三个可选项:

  • never :不展示详细信息,up 或者 down 的状态,默认配置;

  • when-authorized:详细信息将会展示给通过认证的用户。授权的角色可以通过management.endpoint.health.roles 配置;

  • always:对所有用户暴露详细信息。

默认值是never,所以我们直接访问看到的只有UP或DOWN。现在集成了数据库,同时把该项值配置为always,看一下详情:

可以看到整体状态为UP,其中下面的三个组件均为UP,而数据库是MYSQL,检查数据库的语句为“SELECT 1”。同时,还展示了磁盘信息和ping的状态。

现在我们把数据库的用户名和密码故意改错,重启访问可得:

状态为DOWN,组件中db出现了问题,状态为DOWN。问题的详情在error中展示,可以看出是建立连接时出错了。在实践中,我们可以通过health端口监控数据库、Redis、MongoDB、磁盘等健康情况。Actuator预定义的处理类为:DataSourceHealthIndicator, DiskSpaceHealthIndicator, MongoHealthIndicator, RedisHealthIndicator等。

而且每个指标都可以单独的进行开启和关闭,以数据库的为例:

management:
health:
db:
enabled: true

info端点

/info 端点用来查看配置文件 application中以info开头的配置信息,默认情况下 application中并没有 info 节点配置,所以默认为空。

application中添加如下配置:

info:
user:
type: 公众号
name: 程序新视界
wechat: zhuan2quan

访问http://localhost:8080/actuator/info ,展示结果如下:

conditions端点

Spring Boot提供了自动配置功能,使用起来非常方便。但这些自动配置类是什么情况下生效的,是否生效是比较难排查的。此时,可以使用 conditions 在应用运行时查看某个配置类在什么条件下生效,或为什么没有生效。

访问URL:http://localhost:8080/actuator/conditions ,部分返回信息如下:

可以看到某个自动配置类对应的生效条件和提示信息。

shutdown端点

shutdown端点属于操作控制类端点,可以优雅关闭 Spring Boot 应用。需要在配置文件中开启:

management:
endpoint:
shutdown:
enabled: true

该端点只支持POST请求,执行命令及返回结果如下:

curl -X POST "http://localhost:8080/actuator/shutdown" 
{
"message": "Shutting down, bye..."
}

执行之后,会发现应用程序已经被关闭了。由于该端点会关闭应用程序,因此使用需要小心。

configprops端点

在Spring Boot项目中,我们经常会用到@ConfigurationProperties注解来批量注入一些属性,而configprops端点就是用来显示这些被该注解标注的配置类。

比如前面的info配置,我们就可以定义一个类InfoProperties:

@Component
@ConfigurationProperties(prefix = "info")
public class InfoProperties {

private String type;

private String name;

private String wechat;

// 省略getter/setter
}

访问URL:http://localhost:8080/actuator/configprops ,部分信息如下:

不仅可以看到系统中默认集成的配置类信息,还可以看到我们自定义的配置类信息。这里需要注意的是对应的类需要进行实例化(@Component)这里才能够看到。

我们自定义的类中返回了Bean的名称、配置前缀。上面的ProjectInfoProperties还返回了属性信息。

env端点

env端点用于获取全部环境属性,包括application配置文件中的内容、系统变量等。

访问URL:http://localhost:8080/actuator/env ,返回部分信息:

env-toMatch端点

env-toMatch端点与caches和caches-cache类似,一个是获取所有的,一个是获取指定的。这里的env-toMatch端点是获取指定key的环境变量属性。

基本格式为:http://localhost:8080/actuator/env/{toMatch}。 实例URL:http://localhost:8080/actuator/env/info.user.name ,返回结果如下图: 

返回数据信息包括该属性的来源、value值等信息。

loggers端点

/loggers 端点暴露了程序内部配置的所有 logger 的信息,包括不同的package、不同的类的日志级别信息。

访问URL:http://localhost:8080/actuator/loggers ,部分返回结果:

loggers-name端点

loggers-name端点也是logger端点的细分,可以通过name访问某一个logger。

基本请求格式:http://localhost:8080/actuator/loggers/{name} 示例请求URL:http://localhost:8080/actuator/loggers/com.secbro2.SpringbootActuatorApplication ,返回结果如下:

{
"configuredLevel": null,
"effectiveLevel": "INFO"
}

可以看出,启动类的日志级别为INFO。

heapdump端点

heapdump端点会返回一个JVM 堆dump,通过JVM自带的监控工具VisualVM可打开此文件查看内存快照。这是内存优化,基于堆栈层面进行排查的利器。

访问URL:http://localhost:8080/actuator/heapdump 。Mac操作系统下浏览器访问会下载一个名字为heapdump的文件,无后缀,30M。

命令行执行jvisualvm命令,打开VisualVM,依次点击“文件”、“装入”,记得文件类型要选择“堆Dump(.hprof,.*)”,然后选择heapdump。

此时便可以通过工具来进行堆栈信息的分析了。对于线上问题的分析提供了极为便利的方式。

threaddump端点

/threaddump 端点会生成当前线程活动的快照。在日常定位问题的时候查看线程的情况非常有用,主要展示了线程名、线程ID、线程的状态、是否等待锁资源等信息。

访问URL:http://localhost:8080/actuator/threaddump ,部分返回结果:

我们可通过线程快照来排查生产环境的问题。

metrics端点

/metrics 端点用来暴露当前应用的各类重要度量指标,比如:内存信息、线程信息、垃圾回收信息、tomcat、数据库连接池等。2.x版本这里只显示了一个指标的列表。

访问URL:http://localhost:8080/actuator/metrics 。

{
"names": [
"jvm.memory.max",
"jvm.threads.states",
"jvm.gc.pause",
"http.server.requests",
"process.files.max",
"jvm.gc.memory.promoted",
"system.load.average.1m",
"jvm.memory.used",
"jvm.gc.max.data.size",
"jvm.memory.committed",
"system.cpu.count",
"logback.events",
"jvm.buffer.memory.used",
"tomcat.sessions.created",
"jvm.threads.daemon",
"system.cpu.usage",
"jvm.gc.memory.allocated",
"tomcat.sessions.expired",
"jvm.threads.live",
"jvm.threads.peak",
"process.uptime",
"tomcat.sessions.rejected",
"process.cpu.usage",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"tomcat.sessions.active.current",
"tomcat.sessions.alive.max",
"jvm.gc.live.data.size",
"process.files.open",
"jvm.buffer.count",
"jvm.buffer.total.capacity",
"tomcat.sessions.active.max",
"process.start.time"
]
}

/metrics端点可以提供应用运行状态的完整度量指标报告,这项功能非常的实用,但是对于监控系统中的各项监控功能,它们的监控内容、数据收集频率都有所不同,如果我们每次都通过全量获取报告的方式来收集,略显粗暴。官方也是可能是处于此方面的考虑,在Spring Boot 2.x之后,/metrics端点只显示了指标的列表。

如果需要查看具体的某项指标,则可通过/metrics-requiredMetricName端点来实现。

metrics-requiredMetricName端点

metrics-requiredMetricName端点,用于访问指定指标的报告,一般会配合/metrics端点先查出指标列表,然后再查询具体的某个指标。

基本格式:http://localhost:8080/actuator/metrics/{requiredMetricName}。 实例URL:http://localhost:8080/actuator/metrics/jvm.memory.max ,返回结果如下:

{
"name": "jvm.memory.max",
"description": "The maximum amount of memory in bytes that can be used for memory management",
"baseUnit": "bytes",
"measurements": [
{
"statistic": "VALUE",
"value": 5606211583
}
],
"availableTags": [
{
"tag": "area",
"values": [
"heap",
"nonheap"
]
},
{
"tag": "id",
"values": [
"Compressed Class Space",
"PS Survivor Space",
"PS Old Gen",
"Metaspace",
"PS Eden Space",
"Code Cache"
]
}
]
}

上述结果展示了最大可用内存的情况。其他相关指标的展示替换对应的名字进行查看即可。

scheduledtasks端点

/scheduledtasks端点用于展示应用中的定时任务信息。

先在项目中构建两个定时任务,首先在启动类上添加@EnableScheduling开启定时任务功能。然后创建定时任务类:

@Component
public class MyTask {

@Scheduled(cron = "0/10 * * * * *")
public void work() {
System.out.println("I am a cron job.");
}

@Scheduled(fixedDelay = 10000)
public void work1() {
System.out.println("I am a fixedDelay job.");
}
}

其中定义了两种类型的定时任务,work是基于cron实现的定时任务,work1是基于fixedDelay实现的定时任务。

访问URL:http://localhost:8080/actuator/scheduledtasks ,返回结果信息如下:

{
"cron": [
{
"runnable": {
"target": "com.secbro2.job.MyTask.work"
},
"expression": "0/10 * * * * *"
}
],
"fixedDelay": [
{
"runnable": {
"target": "com.secbro2.job.MyTask.work1"
},
"initialDelay": 0,
"interval": 10000
}
],
"fixedRate": [],
"custom": []
}

可以看到,通过该端点可以明确的知道当前应用中定义的定时任务,以及执行模式和频次。

mappings端点

/mappings端点用于描述全部的 URI 路径,以及和控制器的映射关系。这个功能算是比较常用的了,如果想系统的查看URL对应的Controller及方法,可以使用此端点。

访问URL:http://localhost:8080/actuator/mappings ,部分返回结果如下:

至此关于Spring Boot Actuator提供的所有端点介绍完毕。

小结

本文通过对Spring Boot Actuator提供所有端点构建实例并演示结果,本文大多数内容和实例都是全网第一手资料。该框架对排查线上问题,性能优化等都有极大的帮助。而在写本文的过程中也越来越惊叹Actuator的功能强大,强烈推荐用起来。


往期推荐

Spring Boot Actuator集成,难的是灵活运用!

“精通”,不是为了面试,而是为了个人品牌

微服务架构:Nacos本地缓存 PK 微服务优雅下线

微服务:剖析一下源码,Nacos的健康检查竟如此简单

微服务之:服务挂的太干脆,Nacos还没反应过来,怎么办?



如果你觉得这篇文章不错,那么,下篇通常会更好。添加微信好友,可备注“加群”(微信号:zhuan2quan)

一篇文章就看透技术本质的人,
  和花一辈子都看不清的人,
  注定是截然不同的搬砖生涯。
▲ 按关注”程序新视界“,洞察技术内幕
浏览 106
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报