Spring Boot Actuator:配置使用
Spring Boot Actuator简介
Spring Boot Actuator是帮助我们监控和管理Spring Boot应用的一个程序。比如健康检查、审计、统计和HTTP追踪等。这些监控数据我们可以通过HTTP或者JMX轻松获取到。
Actuator同时还可以与外部应用监控系统整合,比如 Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic等。
Demo
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
添加配置
application.yml
management:
server:
port: 9090 #暴露的端口,http通过这个端口过去监控信息
endpoints:
web:
exposure:
include: '*' #允许访问的endpoint:*所有,info,health,beans,env,loggers等
exclude: beans #不允许访问的endpoint
base-path: /actuator # http访问路径,默认:actuator
endpoint:
health:
show-details: always # always允许访问详细数据
metrics:
tags:
application: ${spring.application.name} # 后面prometheus会用到,标志一个应用
上面这些配置都是一些常用的配置,而且相对固定,不用非要记住,只要知道这些项是可配置的就行。下面还会详细介绍这些参数。
启动应用
访问:http://127.0.0.1:9090/actuator
注意:这里的端口是上面配置的(如果没有配置默认和服务端端口一样是8080),路径也是配置的,如果没有配置就是默认的:/actuator
访问结果如下:
将上面的结果格式化之后如下:
这些代表获取每个endpoint的监控数据的路径和模板,下面会详细介绍一下这些endpoint具体有什么作用。
详细配置
暴露Endpoint
Actuator是有一个一个的监控项endpoint组成的,可以简单的通过配置来控制Actuator对外暴露endpoint项,下面是默认的配置:
Property | Default | |
---|---|---|
jmx排除暴露的endpoint | management.endpoints.jmx.exposure.exclude | |
jmx暴露的endpoint | management.endpoints.jmx.exposure.include | * |
http排除暴露的endpoint | management.endpoints.web.exposure.exclude | |
http暴露的endpoint | management.endpoints.web.exposure.include | info, health |
从上面的表格可以看出来 jmx默认开启了所有的endpoint,但是web只开放了info和health。
如果想通过web或jmx访问还需要配置允许访问一般使用exclude来排除访问,用include允许访问,且exclude的优先级高于include
*
代表允许所有,如果是多个就用逗号分隔
*
需要加引号,否者程序会启动失败,这是因为*在spring的配置文件中有特殊含义
允许访问后就可以通过http访问了:http://127.0.0.1:9090/actuator
它会列出所有允许访问的端点和访问路径
启用Endpoint
默认情况下,除shutdown之外的所有端点都处于启用状态. 要启用端点,请使用其management.endpoint. .enabled属性。 以下示例启用shutdown端点:
management.endpoint.shutdown.enabled=true
内置Endpoint
ID | 描述 | JMX | WEB |
---|---|---|---|
auditevents | 显示应用暴露的审计事件(如认证进入、订单失败). | Yes | No |
beans | 显示应用程序中上下文里所有的bean和他们的关系. | Yes | No |
caches | 公开可用的缓存. | Yes | No |
conditions | 提供一份自动配置生效的条件情况,记录哪些自动配置条件通过了,那些没通过. | Yes | No |
configprops | 描述配置属性(包含默认值)如何注入bean. | Yes | No |
env | 获取全部环境属性 | Yes | No |
flyway | 提供一份flyway数据库升级记录信息. | Yes | No |
health | 显示应用程序的健康指标,这些值由HealthIndicator的实现类提供. | Yes | Yes |
httptrace | 显示HTTP足迹(默认显示最近100个HTTP request/repsponse). | Yes | No |
info | 显示应用程序的定制信息,这些信息由info打头的属性提供. | Yes | Yes |
integrationgraph | 显示 Spring Integration图. | Yes | No |
loggers | 显示和修改 配置的loggers. | Yes | No |
liquibase | 显示Liquibase数据库迁移的详细信息. | Yes | No |
metrics | 显示当前应用程序的“指标”信息. | Yes | No |
mappings | 描述全部的Url路径,以及他们的控制器(包含Actuator端点)的映射关系. | Yes | No |
scheduledtasks | 显示应用程序中的计划任务. | Yes | No |
sessions | 如果我们使用了Spring Session 展示应用中的session信息 | Yes | No |
shutdown | 允许应用程序正常关闭. | Yes | No |
threaddump | 显示线程活动的快照. | Yes | No |
heapdump | dump一份java堆信息. | N/A | No |
jolokia | 通过HTTP公开JMX bean(当Jolokia在类路径上时,不适用于WebFlux). | N/A | No |
logfile | 返回日志文件的内容(如果已设置logging.file或logging.path属性). | N/A | No |
prometheus | 以可以由Prometheus服务器抓取的格式公开指标. | N/A | No |
metrics
Actuator的度量单位
http://localhost:9090/actuator/metrics
http://localhost:9090/actuator/metrics/jvm.gc.pause
Prometheus端点
因为现在Actoator经常和Prometheus一起使用,所以下面以Prometheus端点为例详细介绍下Actoator返回的监控信息。
首先要在pom文件中加入Prometheus的依赖
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
然后访问:http://localhost:9090/actuator/prometheus
注意端口和路径是上面配置的,如果没配置过应该使用默认的http://localhost:8080/actuator/prometheus
下面就是部分返回值,可以看到我们关心的大部分指标都在这里
# HELP jvm_gc_pause_seconds Time spent in GC pause
# TYPE jvm_gc_pause_seconds summary
jvm_gc_pause_seconds_count{action="end of minor GC",application="prometheus-test",cause="Metadata GC Threshold",} 1.0
jvm_gc_pause_seconds_sum{action="end of minor GC",application="prometheus-test",cause="Metadata GC Threshold",} 0.007
jvm_gc_pause_seconds_count{action="end of minor GC",application="prometheus-test",cause="Allocation Failure",} 2.0
jvm_gc_pause_seconds_sum{action="end of minor GC",application="prometheus-test",cause="Allocation Failure",} 0.017
jvm_gc_pause_seconds_count{action="end of major GC",application="prometheus-test",cause="Metadata GC Threshold",} 1.0
jvm_gc_pause_seconds_sum{action="end of major GC",application="prometheus-test",cause="Metadata GC Threshold",} 0.071
# HELP jvm_gc_pause_seconds_max Time spent in GC pause
# TYPE jvm_gc_pause_seconds_max gauge
jvm_gc_pause_seconds_max{action="end of minor GC",application="prometheus-test",cause="Metadata GC Threshold",} 0.0
jvm_gc_pause_seconds_max{action="end of minor GC",application="prometheus-test",cause="Allocation Failure",} 0.0
jvm_gc_pause_seconds_max{action="end of major GC",application="prometheus-test",cause="Metadata GC Threshold",} 0.0
# HELP tomcat_sessions_created_sessions_total
# TYPE tomcat_sessions_created_sessions_total counter
tomcat_sessions_created_sessions_total{application="prometheus-test",} 0.0
# HELP system_cpu_count The number of processors available to the Java virtual machine
# TYPE system_cpu_count gauge
system_cpu_count{application="prometheus-test",} 8.0
# HELP tomcat_sessions_active_current_sessions
# TYPE tomcat_sessions_active_current_sessions gauge
tomcat_sessions_active_current_sessions{application="prometheus-test",} 0.0
# HELP jvm_threads_states_threads The current number of threads having NEW state
# TYPE jvm_threads_states_threads gauge
jvm_threads_states_threads{application="prometheus-test",state="runnable",} 13.0
jvm_threads_states_threads{application="prometheus-test",state="new",} 0.0
jvm_threads_states_threads{application="prometheus-test",state="terminated",} 0.0
jvm_threads_states_threads{application="prometheus-test",state="blocked",} 0.0
jvm_threads_states_threads{application="prometheus-test",state="waiting",} 23.0
jvm_threads_states_threads{application="prometheus-test",state="timed-waiting",} 8.0
......略略
自定义Endpoint
首先我们可以看下已有的Endpoint是怎么写的。我们可以模仿他们写一个。
比如我们看下比较简单的InfoEndpoint
@Endpoint(id = "info")
public class InfoEndpoint {
private final List<InfoContributor> infoContributors;
......
@ReadOperation
public Map<String, Object> info() {
Info.Builder builder = new Info.Builder();
for (InfoContributor contributor : this.infoContributors) {
contributor.contribute(builder);
}
Info build = builder.build();
return build.getDetails();
}
}
代码很少,我们一眼可见的就是有两个注解:@Endpoint(id = “info”),@ReadOperation
- 首先说下@Endpoint这个注解,@Endpoint有两个派生WebEndpoint和JmxEndpoint,分别可以支持HTTP和JMX的暴露方式。
- @ReadOperation 这个注解相当于restful api的GET操作,看下图同包下还有两个注解WriteOperation相当于restful api的Post操作,DeleteOperation相当于restful api的DELETE操作。
知道了这个之后,我们就是自己定义一个Endpoint
@Component
@Endpoint(id = "features")
public class FeaturesEndpoint {
private Map<String, Feature> features = new ConcurrentHashMap<>();
@PostConstruct
public void init(){
features.put("max",new Feature(true));
features.put("min",new Feature(false));
}
@ReadOperation
public Map<String, Feature> features() {
return features;
}
@ReadOperation
public Feature feature(@Selector String name) {
return features.get(name);
}
@WriteOperation
public void configureFeature(@Selector String name) {
features.put(name, new Feature(true));
}
@DeleteOperation
public void deleteFeature(@Selector String name) {
features.remove(name);
}
public static class Feature {
//......
}
}
之后重启一下,再次访问http://localhost:9090/actuator/
会发现endpoint列表里多了一个features的端点,说明我们自定义Endpoint成功了,通过这种方式你可以定义自己的Endpoint了。
并且可以使用resetful api的方式查询一个数据,添加一个数据,删除一个数据。