转载自:https://www.zuojl.com/spring-boot-actuator/
在 Spring Boot 的众多模块中,有一个特殊的模块 Actuator ,其主要用来暴露应用本身信息,所以它就是作用于对用于的监控和管理。对于中小团队来说,可以有效的减少监控系统在采集应用指标的开发量。当然,默认提供的功能并不能满足所有用户的需求,因此 Spring Boot 团队也提供了进行自定义监控的实现方式。
Spring Boot 应用集成 Actuator 是非常容易的,只需在 pom 文件中添加如下的代码
org.springframework.boot
spring-boot-starter-actuator
然后启动应用,访问 http://localhost:8080/actuator 将会看到如下的信息
{
"_links": {
"self": {
"href": "http://localhost:8080/actuator",
"templated": false
},
"health": {
"href": "http://localhost:8080/actuator/health",
"templated": false
},
"health-component": {
"href": "http://localhost:8080/actuator/health/{component}",
"templated": true
},
"health-component-instance": {
"href": "http://localhost:8080/actuator/health/{component}/{instance}",
"templated": true
},
"info": {
"href": "http://localhost:8080/actuator/info",
"templated": false
}
}
}
访问其中的其中的健康信息端点 http://localhost:8080/actuator/health 就可以获取到应用的健康信息
{
"status": "UP"
}
默认情况下我们只能获取到关于 health 和 info 的信息,如果需要获取更多的监控信息,需要配置暴露 Set 集合,如下配置暴露所有的监控信息
management:
endpoints:
web:
exposure:
include: "*"
Spring Boot 应用提供了很多的监控信息,下面罗列部分比较常用的功能。
HTTP 跟踪
通过浏览器输入 http://localhost:8080/actuator/httptrace 就可以访问 Spring Boot 提供的 trace 跟踪功能。 trace 通过 InMemoryHttpTraceRepository
类来实现的,默认保留最后 100 条访问数据,当然也可以指定些个性化的设置。比如设置保留最后一条记录。
@Bean
@ConditionalOnMissingBean(InMemoryHttpTraceRepository.class)
public InMemoryHttpTraceRepository inMemoryHttpTraceRepository() {
InMemoryHttpTraceRepository inMemoryHttpTraceRepository = new InMemoryHttpTraceRepository();
inMemoryHttpTraceRepository.setCapacity(1);
return inMemoryHttpTraceRepository;
}
日志查看
Actuator 允许查看日志配置,还允许修改日志等级配置,也可以在线查看日志内容。只需在浏览器中输入如下的地址:
http://localhost:8080/actuator/loggers
堆栈信息
在 Spring Boot 中,可以获取某一时刻虚拟机的线程栈信息,改信息类似使用 JDK 自带的 jstack
命令的输出结果。http://localhost:8080/actuator/threaddump
JDK 提供的 jmap
工具,能够获取内存镜像信息,同样 Actuator 能够将镜像信息下载下来以提供分析 http://localhost:8080/actuator/heapdump 。 将下载下来的 heapdump 文件使用 jhat -port 7000 heapdump
这个命令进行打开,然后访问 http://localhost:7000/oql/ 可以对其进行 OQL 查询来分析内存信息。比如查询 ArrayList 的 size 超出 400 的实例
select s from java.util.ArrayList s where s.size > 400
查看 URL 映射
Actuator 的 mappings 输出所以通过注解 @RequestMapping 设置的 URL 映射,访问如下地址 http://localhost:8080/actuator/mappings 将返回如下相似信息。
{
"handler": "public com.baomidou.mybatisplus.extension.api.R> com.zuojl.lo.modules.sys.controller.UserController.page(int,int)",
"predicate": "{GET /user/list}",
"details": {
"handlerMethod": {
"className": "com.zuojl.lo.modules.sys.controller.UserController",
"name": "page",
"descriptor": "(II)Lcom/baomidou/mybatisplus/extension/api/R;"
},
"requestMappingConditions": {
"consumes": [],
"headers": [],
"methods": [
"GET"
],
"params": [],
"patterns": [
"/user/list"
],
"produces": []
}
}
}
查看 Spring 容器所管理的 Bean
Actuator 的 beans 输出所以 Spring 管理的 Bean ,输出如下
{
"userController": {
"aliases": [],
"scope": "singleton",
"type": "com.zuojl.lo.modules.sys.controller.UserController",
"resource": "file [D:\\IdeaProjects\\lo\\target\\classes\\com\\zuojl\\lo\\modules\\sys\\controller%userController.class]",
"dependencies": [
"userServiceImpl"
]
}
}
其他监控
@ConfigurationProperties
注解的配置信息。编写自己的监控信息
下面简单编写一个输出当前系统时间,并按照指定格式进行格式化。
创建监控实现类
@Endpoint(id = "date")
public class DateEndpoint {
private String format = "yyyy-MM-dd HH:mm:ss";
@ReadOperation
public Map info() {
Map map = new HashMap<>();
Date date = new Date();
map.put("time", date.getTime());
map.put("format", format);
map.put("date", new SimpleDateFormat(format).format(date));
return map;
}
@WriteOperation
public void setFormat(String format) {
this.format = format;
}
}
三个注解 @Endpoint
表示这是一个自定义的监控类,可以通过 id 属性来设置 url 的路径,方法上使用 @ReadOperation
和 @WriteOperation
两个注解来分别表示显示监控指标和动态更改监控指标。
然后将其注册为 Spring 的 Bean
@Configuration
public class DateEndpointConfig {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public DateEndpoint dateEndpoint() {
return new DateEndpoint();
}
}
然后配置暴露监控
management:
endpoints:
web:
exposure:
include: "date"
现在访问 http://localhost:8080/actuator/date 路径将返回如下的信息
{
"date": "2019-01-04 15:27:23",
"format": "yyyy-MM-dd HH:mm:ss",
"time": 1546586843852
}
然后修改 format 的格式
curl -XPOST 'http://127.0.0.1:8080/actuator/date' -H 'Content-Type:application/json' -d '{"format":"yyyy-MM-dd"}'
现在访问将返回如下的信息
{
"date": "2019-01-04",
"format": "yyyy-MM-dd",
"time": 1546587525789
}