如何理解SpringBoot Actuator


写在前面

本文参考自 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-actuatorpom 文件,跟踪依赖关系,我们发现 actuator 的主要代码在 spring-boot-actuator, 自动配置相关的在spring-boot-actuator-autoconfigure 包下,可以尝试浏览包结构,以获取概要信息。


2. 端点


端点提供了我们与actuator所监视的应用程序交互的能力。Spring Boot 本身已经内置了许多端点,例如,health 端点。当然,我们也可以添加自己的端点。

可以启用或禁用每个端点。这将控制是否创建端点及其bean存在于应用程序上下文中。要实现远程访问,还必须通过 JMXHTTP 暴露端点。大多数应用程序选择 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 域发起 GETPOST 请求:

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 是有限的,我们建议仅在开发环境中使用它。对于生产环境,建议使用可用于生产的跟踪或可观察性解决方案,如 ZipkinSpring Cloud Sleuth。或者,创建自己的HttpTraceRepository 来满足您的需求。

httptrace 端点可用于获取关于存储在 HttpTraceRepository 中的请求-响应交换的信息。

以上提到的所有端点都需要通过配置文件对外暴露,配置文件默认只暴露了 health, info 。


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值