Spring Boot Actuator深度解析与实战

🧩 一、什么是 Spring Boot Actuator?

Actuator = "执行器" / "控制器"

它是 Spring Boot 提供的一个模块,用于:

  • 查看应用运行状态(如内存、线程、健康状况)
  • 监控性能指标(metrics)
  • 执行管理操作(如关闭应用、刷新配置)

这些功能通过一系列 HTTP 接口(称为"端点 endpoints") 暴露出来。

默认路径:/actuator

例如:

  • GET /actuator/health → 查看服务是否健康
  • GET /actuator/metrics → 获取 JVM 内存、CPU 使用率等
  • GET /actuator/env → 查看环境变量

🔍 分章节详解


✅ 6.2.5. Hypermedia for Actuator Web Endpoints(超媒体发现页)

核心意思:

提供一个"入口页面",列出所有可用的 Actuator 端点链接。

关键点解释:
内容 解释
/actuator 是"发现页" 访问这个 URL,会返回一个 JSON 列表,包含所有已启用的 endpoint 链接(比如 /health, /metrics
自定义管理路径时自动迁移 如果你在 application.yml 中设置了 management.server.base-path=/manage,那么发现页就变成 /manage
设置为 / 时禁用 如果把 management context path 设成根路径 /,为了避免和其他接口冲突,发现页会被关闭

📌 示例:

访问 http://localhost:8080/actuator 得到如下结果(部分):

json 复制代码
{
  "_links": {
    "self": { "href": "/actuator" },
    "health": { "href": "/actuator/health" },
    "metrics": { "href": "/actuator/metrics" },
    "env": { "href": "/actuator/env" }
  }
}

👉 这叫 HATEOAS 风格(Hypermedia as the Engine of Application State),即"通过链接导航系统"。


✅ 6.2.6. CORS Support(跨域支持)

核心意思:

允许浏览器从其他域名访问 Actuator 的 API(比如前端管理系统调用后端的 /actuator/health)。

默认情况:

CORS 被禁用

只有当你显式配置了 allowed-origins,才开启。

示例配置(application.yml):
yaml 复制代码
management:
  endpoints:
    web:
      cors:
        allowed-origins: https://example.com
        allowed-methods: GET,POST
        allowed-headers: "*"
        max-age: 3600

这表示:

  • 允许来自 https://example.com 的请求
  • 只能使用 GET 和 POST 方法
  • 支持任意 header
  • 缓存预检请求 1 小时

💡 注意:需要 Spring MVC 或 WebFlux 才能生效。


✅ 6.2.7. Implementing Custom Endpoints(实现自定义端点)

你可以自己写代码来添加新的监控接口!

方法一:通用端点 @Endpoint(推荐 ✅)
java 复制代码
@Component
@Endpoint(id = "custom")
public class CustomEndpoint {

    @ReadOperation
    public CustomData getData() {
        return new CustomData("test", 5);
    }

    @WriteOperation
    public void updateData(String name, int counter) {
        // 处理更新逻辑
    }
}

✅ 特点:

  • 同时暴露在 JMX 和 HTTP
  • 技术无关(不依赖 Spring MVC/Jersey)
  • 推荐用于通用场景
注解 对应 HTTP 方法 场景
@ReadOperation GET 查询数据
@WriteOperation POST 修改数据
@DeleteOperation DELETE 删除数据

方法二:Web 专属端点(@WebEndpoint)
java 复制代码
@WebEndpoint(id = "webonly")
public class WebOnlyEndpoint {
    @ReadOperation
    public String status() {
        return "OK";
    }
}

⚠️ 特点:

  • 只暴露在 HTTP 上
  • 不出现在 JMX 中
  • 更轻量,适合只做 Web 监控

方法三:增强已有端点(@EndpointWebExtension)

你想给现有的 health 端点加个额外的 Web 功能?可以用这个。

java 复制代码
@EndpointWebExtension(endpoint = HealthEndpoint.class)
public class CustomHealthWebExtension {

    @ReadOperation
    public Map<String, Object> customHealthInfo() {
        return Collections.singletonMap("custom", "info");
    }
}

这样就在原有 /actuator/health 基础上增加了新能力。


方法四:完全自由控制(@ControllerEndpoint / @RestControllerEndpoint)

如果你非要使用 Spring MVC 的注解(如 @GetMapping, @RequestBody),可以这么做:

java 复制代码
@RestControllerEndpoint(id = "admin")
public class AdminController {

    @GetMapping("/pause")
    public String pauseApp() {
        // 暂停应用逻辑
        return "paused";
    }
}

⚠️ 缺点:

  • ❌ 不能用于 JMX
  • ❌ 不能用于 Jersey 或非 Spring Web 框架
  • ❌ 可移植性差

👉 所以官方建议:优先使用 @Endpoint,除非必须用 MVC 注解。


🔁 输入参数处理(Receiving Input)

如何接收参数?

无论是 GET 参数还是 POST JSON,都可以直接作为方法参数注入。

示例:
java 复制代码
@WriteOperation
public void updateUser(String name, int age) {
    // name 来自 query 参数或 JSON 字段
    // age 同理
}
请求示例:
http 复制代码
POST /actuator/custom?name=Tom
Content-Type: application/json

{
  "age": 25
}

name="Tom" 来自 URL 参数

age=25 来自 JSON body

✅ 自动拼接!

注意事项:
  • 默认参数是必填的
  • @Nullable 表示可选
  • 方法签名只能用基本类型或简单对象字段映射(不能传整个复杂对象)
  • Java 编译需加 -parameters(Maven/Gradle 插件默认已开启)

⚙️ Web Endpoint Request Predicates(请求匹配规则)

每个端点的操作都会自动生成一个"请求匹配器"。

1. 路径(Path)

格式:/{base-path}/{endpoint-id}

默认 base-path = /actuator

例子:

  • 端点 ID 是 sessions → 路径是 /actuator/sessions
  • 如果加了 @Selector
java 复制代码
@ReadOperation
public Session getSession(@Selector String id) {
    // ...
}

→ 路径变成 /actuator/sessions/{id}

支持通配符:

java 复制代码
@ReadOperation
public List<String> list(@Selector(match = ALL_REMAINING) String[] parts) {
    // 匹配 /actuator/path/to/file
}

2. HTTP 方法映射

Operation HTTP Method
@ReadOperation GET
@WriteOperation POST
@DeleteOperation DELETE

3. Content-Type(Consumes)

操作类型 consumes 类型
@WriteOperation(带 body) application/vnd.spring-boot.actuator.v2+json, application/json
其他操作 空(不限制)

👉 支持版本化媒体类型,便于未来升级协议。


4. 返回类型(Produces)

根据返回值决定响应类型:

返回值 Produces
void / Void (无 content-type)
Resource(文件) application/octet-stream
其他对象 application/vnd.spring-boot.actuator.v2+json, application/json

5. 响应状态码(Status Code)

情况 HTTP Status
@ReadOperation 返回值 200 OK
@ReadOperation 无返回值 404 Not Found
@WriteOperation / @DeleteOperation 有返回值 200 OK
@WriteOperation / @DeleteOperation 无返回值 204 No Content
缺少必要参数 or 类型转换失败 400 Bad Request

6. Range 请求(断点续传)

如果返回的是 Resource(比如日志文件),并且使用的是 Spring MVC 或 WebFlux,则支持 HTTP Range 请求(可用于下载大文件的部分内容)。

🚫 不支持 Jersey。


7. 安全控制(Security)

可以在方法参数中获取当前用户信息:

java 复制代码
@ReadOperation
public String secureData(Principal principal) {
    if (principal == null) {
        return "anonymous";
    }
    return "Hello " + principal.getName();
}

// 或者更强大的权限判断
@ReadOperation
public boolean isAdmin(SecurityContext securityContext) {
    return securityContext.isUserInRole("ADMIN");
}

👉 可与 Spring Security 集成,做细粒度权限控制。


8. Servlet 端点(@ServletEndpoint)

如果你想封装一个已有的 Servlet 作为监控端点:

java 复制代码
@ServletEndpoint(id = "my-servlet")
public class MyServletEndpoint implements Supplier<EndpointServlet> {
    @Override
    public EndpointServlet get() {
        return new EndpointServlet(MyLegacyServlet.class);
    }
}

⚠️ 局限性强,仅限 Servlet 容器使用。


✅ 总结:四种创建端点的方式对比

方式 注解 是否支持 JMX 是否支持 Web 是否可移植 推荐程度
通用端点 @Endpoint ✅ 最高 ⭐⭐⭐⭐⭐
Web 专属 @WebEndpoint ⭐⭐⭐⭐
扩展已有端点 @EndpointWebExtension ⭐⭐⭐⭐
MVC 控制器风格 @ControllerEndpoint ✅(仅 Spring Web) ⭐⭐

💡 实际应用场景举例

场景 1:做一个"清理缓存"的管理接口

java 复制代码
@Endpoint(id = "clearcache")
public class ClearCacheEndpoint {

    @Autowired
    private CacheManager cacheManager;

    @WriteOperation
    public String clearAllCaches() {
        cacheManager.getCacheNames().forEach(name ->
            cacheManager.getCache(name).clear()
        );
        return "All caches cleared.";
    }
}

访问:POST /actuator/clearcache


场景 2:查看某个任务的状态(带 ID)

java 复制代码
@Endpoint(id = "tasks")
public class TaskEndpoint {

    @ReadOperation
    public TaskStatus getStatus(@Selector String taskId) {
        return taskService.getStatus(taskId);
    }
}

访问:GET /actuator/tasks/login-job


✅ 最佳实践建议

  1. 优先使用 @Endpoint + @ReadOperation/@WriteOperation
  2. 避免使用 @ControllerEndpoint,除非必须用 @RequestBody 等高级特性
  3. 编译时确保开启 -parameters(Spring Boot 默认已开)
  4. 敏感端点要加安全认证(配合 Spring Security)
  5. 生产环境不要暴露所有端点!
yaml 复制代码
# application-prod.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info

📚 学习资源


一句话总结

这段文档讲的是:如何通过标准和自定义方式,在 Spring Boot 中暴露监控接口,并精确控制它们的路径、参数、安全性、输出格式等行为。

如果你正在开发微服务监控平台、内部运维工具或需要深度集成健康检查系统,这部分知识非常关键!

需要我给你写一个完整的自定义 Actuator 端点示例吗?包括 Maven 配置、Java 代码、测试请求等。

相关推荐
Propeller16 分钟前
【Android】模板化解决复杂场景的滑动冲突问题
android·java
渡我白衣19 分钟前
深入 Linux 内核启动:从按下电源到用户登录的全景解剖
java·linux·运维·服务器·开发语言·c++·人工智能
七夜zippoe20 分钟前
Java 9+模块化系统(JPMS)详解:设计与迁移实践
java·开发语言·maven·模块化·jmm
techzhi30 分钟前
Intellij idea 注释模版
java·python·intellij-idea
bagadesu31 分钟前
MySQL----case的用法
java·后端
what_201835 分钟前
idea启动项目配置环境变量(nacos 命名空间)
java·开发语言
Slow菜鸟37 分钟前
Java 开发环境安装指南(三) | Maven 安装
java
Fantasydg41 分钟前
JSP学习
java·开发语言·学习
太空程序猿1 小时前
数据类型与变量
java·开发语言
信仰_2739932431 小时前
RocketMQ事务消息实现订单创建 + 扣减库存
java·rocketmq·java-rocketmq