Spring Boot Actuator自定义端点

好的,各位观众老爷们,欢迎来到“Spring Boot Actuator 之自定义端点:我的地盘我做主”专场讲座!我是你们的老朋友,代码界的段子手,今天要带大家玩转 Spring Boot Actuator 的自定义端点,让你的监控系统不再千篇一律,而是充满个性,独具匠心!

一、Actuator:监控界的瑞士军刀

首先,咱们来简单回顾一下 Actuator 是个啥玩意儿。简单来说,它就是 Spring Boot 自带的一套监控、管理和审计工具集,就像瑞士军刀一样,功能强大,应有尽有。通过 Actuator,你可以轻松获取应用程序的健康状况、指标数据、配置信息等等,而无需编写大量的重复代码。

Actuator 提供的默认端点包括:

  • /health: 应用健康状况,告诉你应用是 "UP" 还是 "DOWN"。
  • /metrics: 各种指标数据,比如 JVM 内存使用情况、HTTP 请求计数等等。
  • /info: 应用基本信息,比如版本号、构建时间等等。
  • /beans: Spring 容器中所有的 Bean 定义。
  • /env: 应用环境变量。
  • /configprops: 配置属性。
  • /mappings: 请求映射关系。
  • /loggers: 日志配置。
  • /threaddump: 线程堆栈信息。
  • /heapdump: 生成堆转储文件。

这些端点就像是 Actuator 这把瑞士军刀上的各种工具,可以满足我们大部分的监控需求。但是,人生不如意事十之八九,总有一些特殊的监控需求,是默认端点无法满足的。这时候,就需要我们祭出 “自定义端点” 这把杀手锏了!

二、为什么要自定义端点?

你可能会问,既然 Actuator 已经提供了这么多端点,为什么还要自定义呢?原因很简单,就像穿衣服一样,默认的尺码可能不合身,需要量身定制才行。

举个栗子 🌰:

  • 你想监控某个业务指标: 比如用户注册数量、订单完成数量等等,这些指标是 Actuator 默认没有提供的。
  • 你想暴露一些敏感信息: 比如数据库连接池的状态、缓存的命中率等等,这些信息默认是隐藏的,需要自定义端点才能暴露出来。
  • 你想执行一些管理操作: 比如清理缓存、重启服务等等,这些操作需要自定义端点才能实现。
  • 你就是想玩点不一样的: 比如暴露一些彩蛋信息,让你的监控系统更加有趣。

总之,自定义端点可以让你更加灵活地监控和管理你的应用程序,让你的监控系统更加个性化,更加实用。

三、自定义端点的三种姿势

Spring Boot 提供了三种方式来自定义 Actuator 端点:

  1. @Endpoint: 最基本的方式,适用于简单的端点,只需要返回一些数据即可。
  2. @WebEndpoint: 适用于需要通过 HTTP 协议访问的端点,可以指定 HTTP 方法(GET、POST、PUT、DELETE 等)。
  3. @RestControllerEndpoint: 适用于需要返回复杂数据结构(比如 JSON)的端点,可以像普通的 Spring MVC Controller 一样使用。

这三种方式就像是三种不同的武器,可以根据不同的场景选择合适的武器。

四、@Endpoint:简单粗暴的输出

@Endpoint 是最简单的自定义端点方式,只需要定义一个类,并用 @Endpoint 注解标注即可。

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;

@Component
@Endpoint(id = "my-endpoint")
public class MyEndpoint {

    @ReadOperation
    public String hello() {
        return "Hello from my custom endpoint!";
    }
}
  • @Endpoint(id = "my-endpoint"): 指定端点的 ID,可以通过 /actuator/my-endpoint 来访问。
  • @ReadOperation: 指定这是一个只读操作,相当于 HTTP 的 GET 请求。
  • hello(): 端点的处理方法,返回一个字符串。

启动应用后,访问 /actuator/my-endpoint,就可以看到 "Hello from my custom endpoint!" 了。

特点:

  • 简单易用,适合简单的端点。
  • 只能返回简单的数据类型,比如字符串、数字、布尔值等。
  • 不支持 HTTP 方法,只能通过 GET 请求访问。

适用场景:

  • 返回一些简单的配置信息。
  • 暴露一些简单的状态信息。
  • 提供一些简单的调试接口。

五、@WebEndpoint:HTTP 协议的加持

@WebEndpoint 可以让你自定义的端点支持 HTTP 协议,可以指定 HTTP 方法(GET、POST、PUT、DELETE 等),还可以接收请求参数。

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.stereotype.Component;

@Component
@Endpoint(id = "user")
public class UserEndpoint {

    private final Map<String, User> users = new ConcurrentHashMap<>();

    @ReadOperation
    public Collection<User> getAllUsers() {
        return users.values();
    }

    @ReadOperation
    public User getUser(@Selector String username) {
        return users.get(username);
    }

    @PostConstruct
    public void init() {
        users.put("admin", new User("admin", "管理员"));
        users.put("user", new User("普通用户", "user"));
    }

    static class User {
        private String username;
        private String role;

        public User(String username, String role) {
            this.username = username;
            this.role = role;
        }

        public String getUsername() {
            return username;
        }

        public String getRole() {
            return role;
        }
    }
}
  • @Selector String username: 指定这是一个路径参数,可以通过 /actuator/user/{username} 来访问。
  • getUser(@Selector String username): 根据用户名获取用户信息。

访问 /actuator/user 可以获取所有用户的信息,访问 /actuator/user/admin 可以获取 admin 用户的信息。

特点:

  • 支持 HTTP 协议,可以指定 HTTP 方法。
  • 可以接收请求参数。
  • 可以返回复杂的数据类型,比如 JSON。

适用场景:

  • 提供 RESTful 风格的 API 接口。
  • 需要接收请求参数的端点。
  • 需要返回复杂数据结构的端点。

六、@RestControllerEndpoint:MVC 的亲儿子

@RestControllerEndpoint 就像是 Spring MVC Controller 的亲儿子,可以像普通的 Controller 一样使用,可以使用 @RequestMapping@GetMapping@PostMapping 等注解,可以返回 JSON 数据,可以处理复杂的业务逻辑。

import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestControllerEndpoint(id = "config")
public class ConfigEndpoint {

    private final Map<String, String> config = new HashMap<>();

    @GetMapping
    public Map<String, String> getAllConfig() {
        return config;
    }

    @PostMapping("/{key}")
    public ResponseEntity<String> setConfig(@PathVariable String key, @RequestBody String value) {
        config.put(key, value);
        return ResponseEntity.ok("Config " + key + " set to " + value);
    }

    @DeleteMapping("/{key}")
    public ResponseEntity<String> deleteConfig(@PathVariable String key) {
        config.remove(key);
        return ResponseEntity.ok("Config " + key + " deleted");
    }
}
  • @RestControllerEndpoint(id = "config"): 指定端点的 ID 为 config,可以通过 /actuator/config 来访问。
  • @GetMapping: 处理 GET 请求,获取所有配置信息。
  • @PostMapping("/{key}"): 处理 POST 请求,设置配置信息。
  • @DeleteMapping("/{key}"): 处理 DELETE 请求,删除配置信息。

访问 /actuator/config 可以获取所有配置信息,通过 POST 请求 /actuator/config/{key} 可以设置配置信息,通过 DELETE 请求 /actuator/config/{key} 可以删除配置信息。

特点:

  • 完全兼容 Spring MVC Controller 的功能。
  • 可以使用各种 Spring MVC 注解。
  • 可以返回 JSON 数据。
  • 可以处理复杂的业务逻辑。

适用场景:

  • 需要提供 RESTful 风格的 API 接口。
  • 需要处理复杂的业务逻辑的端点。
  • 需要返回 JSON 数据的端点。

七、安全性:保护你的 Actuator 端点

Actuator 端点暴露了应用程序的很多敏感信息,如果不加以保护,可能会被恶意攻击者利用。因此,我们需要对 Actuator 端点进行安全保护。

Spring Boot 提供了多种方式来保护 Actuator 端点:

  1. HTTP Basic 认证: 最简单的方式,只需要配置用户名和密码即可。
  2. Spring Security: 最强大的方式,可以实现各种复杂的认证和授权策略。
  3. 防火墙: 通过防火墙限制对 Actuator 端点的访问。

HTTP Basic 认证:

application.propertiesapplication.yml 中配置以下属性:

management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
management.security.enabled=true
management.endpoints.web.base-path=/actuator
security.user.name=admin
security.user.password=password

这样,访问 Actuator 端点就需要输入用户名和密码了。

Spring Security:

如果你需要更加复杂的认证和授权策略,可以使用 Spring Security。首先,引入 Spring Security 的依赖:

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

然后,配置 Spring Security:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/actuator/**").authenticated()
                .anyRequest().permitAll()
                .and()
                .httpBasic();
    }
}

这样,访问 /actuator/** 下的所有端点都需要认证。

防火墙:

你也可以通过防火墙限制对 Actuator 端点的访问,只允许特定的 IP 地址访问。

八、总结:打造你的专属监控系统

通过自定义 Actuator 端点,你可以打造一个专属的监控系统,可以监控任何你感兴趣的指标,可以执行任何你需要的管理操作,可以让你的应用程序更加安全、可靠、高效。

记住,自定义端点就像是乐高积木,你可以根据自己的需求,自由组合,搭建出各种各样的监控系统。只要你有想法,没有什么是不可能的!

好了,今天的讲座就到这里,希望大家能够学以致用,打造出属于自己的个性化监控系统! 如果大家还有什么问题,可以在评论区留言,我会尽力解答。

表格总结:

特性 @Endpoint @WebEndpoint @RestControllerEndpoint
HTTP 协议支持
HTTP 方法指定 否 (默认 GET) 可以指定 可以指定
请求参数接收 部分支持 (通过 Selector) 支持 支持
返回数据类型 简单数据类型 复杂数据类型 复杂数据类型
Spring MVC 支持 部分支持 完全支持
适用场景 简单状态监控 RESTful API 接口 复杂业务逻辑 API

最后,送大家一句箴言:代码虐我千百遍,我待代码如初恋! 💖 咱们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注