好的,各位观众老爷们,欢迎来到“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 端点:
@Endpoint: 最基本的方式,适用于简单的端点,只需要返回一些数据即可。@WebEndpoint: 适用于需要通过 HTTP 协议访问的端点,可以指定 HTTP 方法(GET、POST、PUT、DELETE 等)。@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 端点:
- HTTP Basic 认证: 最简单的方式,只需要配置用户名和密码即可。
- Spring Security: 最强大的方式,可以实现各种复杂的认证和授权策略。
- 防火墙: 通过防火墙限制对 Actuator 端点的访问。
HTTP Basic 认证:
在 application.properties 或 application.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 |
最后,送大家一句箴言:代码虐我千百遍,我待代码如初恋! 💖 咱们下期再见!