文章目录
写在前面
本文参考自 Spring-Boot 官方文档,介绍了 actuator 常用特性,关于具体的配置可参考官方文档。
在官方文档是如何定义 Spring Boot Actuator
的? 生产就绪 的特性。
Spring Boot 包含许多附加功能,可以帮助您在将应用程序推向生产环境时对其进行监视和管理。您可以选择使用 HTTP 端点或
JMX
来管理和监视应用程序。审计、健康状况和指标收集也可以自动应用到您的应用程序中。
1. 启用
启用 actuator
非常简单,基于 Maven 的项目,只需要导入以下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
根据 spring-boot-starter-actuator
的 pom
文件,跟踪依赖关系,我们发现 actuator
的主要代码在 spring-boot-actuator
, 自动配置相关的在spring-boot-actuator-autoconfigure
包下,可以尝试浏览包结构,以获取概要信息。
2. 端点
端点提供了我们与actuator
所监视的应用程序交互的能力。Spring Boot 本身已经内置了许多端点,例如,health
端点。当然,我们也可以添加自己的端点。
可以启用或禁用每个端点。这将控制是否创建端点及其bean存在于应用程序上下文中。要实现远程访问,还必须通过
JMX
或HTTP
暴露端点。大多数应用程序选择 HTTP,其中端点的ID和前缀/actuator
被映射到一个URL。例如,默认情况下,健康端点映射到/actuator/health
。
查看 @Endpoint
注解,该注解的文档说明指出该注解是为运行的应用提供 actuator
端点。端点可以通过 JMX
和 HTTP 技术对外暴露。所以我们很容易在该注解类所处的包结构下,发现 web 以及 jmx
包。
大多数 @Endpoint 类会声明一个或多个
@ReadOperation
,@WriteOperation
,
@DeleteOperation
注解的方法,这些方法将适应暴露的技术自动执行。
2.1 实现自定义端点
如何 实现自定义端点 呢?最好的样例就是来自源码,我们可以查看HealthEndpoint
端点。
@Endpoint(id = "health")
public class HealthEndpoint {
private final HealthIndicator healthIndicator;
/**
* Create a new {@link HealthEndpoint} instance that will use the given
* {@code healthIndicator} to generate its response.
* @param healthIndicator the health indicator
*/
public HealthEndpoint(HealthIndicator healthIndicator) {
Assert.notNull(healthIndicator, "HealthIndicator must not be null");
this.healthIndicator = healthIndicator;
}
@ReadOperation
public Health health() {
return this.healthIndicator.health();
}
/**
* Return the {@link Health} of a particular component or {@code null} if such
* component does not exist.
* @param component the name of a particular {@link HealthIndicator}
* @return the {@link Health} for the component or {@code null}
*/
@ReadOperation
public Health healthForComponent(@Selector String component) {
HealthIndicator indicator = getNestedHealthIndicator(this.healthIndicator, component);
return (indicator != null) ? indicator.health() : null;
}
/**
* Return the {@link Health} of a particular {@code instance} managed by the specified
* {@code component} or {@code null} if that particular component is not a
* {@link CompositeHealthIndicator} or if such instance does not exist.
* @param component the name of a particular {@link CompositeHealthIndicator}
* @param instance the name of an instance managed by that component
* @return the {@link Health} for the component instance of {@code null}
*/
@ReadOperation
public Health healthForComponentInstance(@Selector String component, @Selector String instance) {
HealthIndicator indicator = getNestedHealthIndicator(this.healthIndicator, component);
HealthIndicator nestedIndicator = getNestedHealthIndicator(indicator, instance);
return (nestedIndicator != null) ? nestedIndicator.health() : null;
}
private HealthIndicator getNestedHealthIndicator(HealthIndicator healthIndicator, String name) {
if (healthIndicator instanceof CompositeHealthIndicator) {
return ((CompositeHealthIndicator) healthIndicator).getRegistry().get(name);
}
return null;
}
}
我们需要注意的是 该类需要被声明为 Bean ( Intellij
自动提示的)。观察上诉类,我们需要关心的仅仅是方法的注解,查看注解文档,实现自己的端点:
@Endpoint(id = "appInfo")
public class AppInfoEndpoint {
/**
* app 描述信息
*/
private String desc;
/**
* app 作者信息
*/
private Author author;
public AppInfoEndpoint(String desc, Author author){
this.desc = desc;
this.author = author;
}
/**
* 读取描述: HTTP GET请求:http://localhost:8089/actuator/appInfo
*/
@ReadOperation
public String getDesc(){
return this.desc;
}
/**
* 读取作者信息:HTTP GET请求:http://localhost:8089/actuator/appInfo/1
*/
@ReadOperation
public Author getAuthor(@Selector Integer type ){
if(type.intValue() == 1){
return author;
}
return null;
}
/**
* 修改作者姓名,并返回旧的名称:HTTP POST请求:http://localhost:8089/actuator/appInfo/DUO
*/
@WriteOperation
public String updateAuthor(@Selector String name){
String oldName = author.getName();
this.author.setName(name);
return oldName;
}
}
声明 Bean :
@Bean
public AppInfoEndpoint appInfoEndpoint(){
Author author = new Author();
author.setName("duofei");
author.setAge(25);
author.setEmail("662@.com");
return new AppInfoEndpoint("我仅仅是一个测试程序", author);
}
在配置文件中对外暴露该端点:
management:
endpoints:
web:
exposure:
include: appInfo,health
2.2 实现安全的端点
如果存在Spring Security
,则默认情况下使用Spring Security的内容协商策略保护端点。例如,如果希望为HTTP 端点配置自定义安全性,只允许具有特定角色的用户访问它们,Spring Boot 提供了一些方便的RequestMatcher
对象,可以将它们与Spring security结合使用。
导入spring-boot-starter-security
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
这时运行示例,我们能在控制台获取生成的密码,在访问时,需要这样请求:
curl -X GET http://user:180ac8e3-d614-47ca-984b-d22a21769fd0@localhost:8089/actuator/appInfo/1
2.3 跨域支持
CORS
支持在默认情况下是禁用的,并且只在 management.endpoints.web.cors.allowed-origins
设置了值后启用。下面的配置允许从example.com
域发起 GET
和 POST
请求:
management.endpoints.web.cors.allowed-origins=https://example.com
management.endpoints.web.cors.allowed-methods=GET,POST
3.基于 HTTP 的监控和管理
如果开发web应用程序,Spring Boot actuator 将自动配置所有通过 HTTP 公开的已启用端点。默认约定是使用带有 /actuator
作为URL路径前缀。
3.1 自定义管理端点路径
有时,为管理端点定制前缀是有用的。例如,您的应用程序可能已经将/actuator
用于其他目的。
management.endpoints.web.base-path=/manage
上诉我们对端点的访问由/actuator/appInfo
变为了 /manage/appInfo
。
如果希望将端点映射到不同的路径,可以使用 management.endpoints.web.path-mapping
属性。
management.endpoints.web.base-path=/
management.endpoints.web.path-mapping.health=healthcheck
/actuator/health
映射为 /healthcheck
。
3.2 自定义管理端口
通过使用不同的HTTP端口来公开端点:
management.server.port=8081
3.3 禁用 HTTP 端点
如果,并不想暴露任何基于 HTTP 的端点,可以设置管理端口号为 -1
。
management.server.port=-1
或者
management.endpoints.web.exposure.exclude=*
4. 日志记录器
Spring Boot 执行器包括在运行时查看和配置应用程序日志级别的功能。您可以查看整个列表或单个日志记录器的配置,它由显式配置的日志级别和日志框架提供给它的有效日志级别组成。这些级别可以是:
TRACE
DEBUG
INFO
WARN
ERROR
FATAL
OFF
null
null
表示没有显式配置。
为了配置日志记录器,使用 POST 请求访问资源 URL (/actuator/loggers
):
{
"configuredLevel": "DEBUG"
}
重置日志记录期的级别,仅仅需要为 configuredLevel
传递一个 null
。
更具体的可以分析
LoggersEndpoint
类。
5. HTTP 跟踪
可以通过在应用程序的配置中提供 HttpTraceRepository
类型的bean来启用HTTP跟踪。为了方便起见,Spring Boot提供了一个InMemoryHttpTraceRepository
,它默认存储最后100个请求-响应交换的跟踪。与其他跟踪解决方案相比,InMemoryHttpTraceRepository
是有限的,我们建议仅在开发环境中使用它。对于生产环境,建议使用可用于生产的跟踪或可观察性解决方案,如 Zipkin
或 Spring Cloud Sleuth
。或者,创建自己的HttpTraceRepository
来满足您的需求。
httptrace
端点可用于获取关于存储在 HttpTraceRepository
中的请求-响应交换的信息。
以上提到的所有端点都需要通过配置文件对外暴露,配置文件默认只暴露了 health, info 。