spring boot actuator 是 spring boot 框架提供的生产环境监控和管理工具集,广泛应用于微服务和企业级系统。根据 2024 年 stack overflow 开发者调查,spring boot 在 java 生态中占据主导地位,约 60% 的 java 开发者使用它构建高并发应用(如电商、微服务)。actuator 提供开箱即用的端点(如健康检查、指标、日志管理),并支持自定义端点以满足特定监控需求。本文深入剖析 actuator 的用途、核心功能、自定义监控端点的实现方法,并以电商订单处理系统(qps 10 万,p99 延迟 < 10ms)为例,展示如何通过自定义端点监控订单处理性能。
一、背景与需求分析
1.1 spring boot actuator 的重要性
- 定义:actuator 是 spring boot 提供的模块,通过 http 或 jmx 暴露应用程序运行时的管理端点,用于监控和操作。
- 功能:
- 健康检查:检测应用及依赖(如数据库、缓存)状态。
- 性能指标:收集 cpu、内存、请求延迟等 metrics。
- 运行时管理:动态调整日志级别、关闭应用。
- 可扩展性:支持自定义端点。
- 挑战:
- 安全性:端点暴露需权限控制。
- 性能:高频访问端点可能影响系统。
- 复杂性:自定义端点需熟悉 spring 机制。
- 集成:与 prometheus、grafana 等监控系统结合。
1.2 高并发场景需求
- 场景:电商订单处理系统,处理订单创建和查询,日活 1000 万,qps 10 万。
- 功能需求:
- 健康检查:监控数据库、redis 连接状态。
- 性能监控:统计订单处理延迟、吞吐量。
- 自定义端点:提供订单统计端点(如成功率)。
- 动态管理:调整日志级别以调试问题。
- 非功能需求:
- 性能:p99 延迟 < 10ms,吞吐量 > 10 万 qps。
- 可用性:99.99%(宕机 < 52 分钟/年)。
- 资源效率:cpu 利用率 < 70%,内存 < 16gb/节点。
- 安全性:端点需认证授权。
- 可维护性:代码清晰,易于扩展。
- 数据量:
- 日订单:1 亿(10 万 qps × 3600s × 24h)。
- 单订单:约 1kb。
- 日操作:100 亿次(1 亿订单 × 100 次操作/订单)。
1.3 技术挑战
- 监控覆盖:全面收集系统和业务指标。
- 性能:端点响应不能影响业务。
- 安全性:防止未授权访问。
- 扩展性:自定义端点支持复杂逻辑。
- 集成:与外部监控系统无缝对接。
1.4 目标
- 正确性:监控数据准确。
- 性能:p99 延迟 < 10ms,qps > 10 万。
- 稳定性:cpu/内存 < 70%。
- 安全性:端点受保护。
- 成本:单节点 < 0.01 美元/qps。
1.5 技术栈
组件 | 技术选择 | 优点 |
---|---|---|
编程语言 | java 21 | 性能优异、生态成熟 |
框架 | spring boot 3.3 | 集成丰富,简化开发 |
数据库 | mysql 8.0 | 高性能、事务支持 |
缓存 | redis 7.2 | 低延迟、高吞吐 |
监控 | actuator + micrometer + prometheus 2.53 | 实时指标、集成 grafana |
日志 | slf4j + logback 1.5 | 高性能、异步日志 |
安全 | spring security 6.3 | 强大的认证授权 |
容器管理 | kubernetes 1.31 | 自动扩缩容、高可用 |
ci/cd | jenkins 2.426 | 自动化部署 |
二、spring boot actuator 核心功能
2.1 内置端点
actuator 提供多种开箱即用端点(spring boot 3.3):
端点 | 路径 | 用途 |
---|---|---|
/health | /actuator/health | 应用及依赖健康状态 |
/metrics | /actuator/metrics | 性能指标(如 cpu、内存、http 请求) |
/info | /actuator/info | 应用元数据(如版本、环境) |
/loggers | /actuator/loggers | 查看/修改日志级别 |
/shutdown | /actuator/shutdown | 优雅关闭应用(默认禁用) |
/prometheus | /actuator/prometheus | prometheus 格式指标导出 |
启用端点:
management: endpoints: web: exposure: include: health,metrics,info,loggers,prometheus
2.2 健康检查
- 机制:聚合应用及依赖(如 db、redis)状态。
- 示例:
curl http://localhost:8080/actuator/health {"status":"up","components":{"db":{"status":"up"},"redis":{"status":"up"}}}
自定义健康检查:
@component public class customhealthindicator implements healthindicator { @override public health health() { return health.up().withdetail("custom", "ok").build(); } }
2.3 性能指标
- micrometer 集成:支持 prometheus、grafana 等。
- 示例:
curl http://localhost:8080/actuator/metrics/jvm.memory.used {"name":"jvm.memory.used","measurements":[{"statistic":"value","value":123456789}]}
自定义指标:
meterregistry registry; counter counter = registry.counter("orders.created"); counter.increment();
2.4 运行时管理
动态日志:
curl -x post -h "content-type: application/json" -d '{"configuredlevel":"debug"}' \ http://localhost:8080/actuator/loggers/com.example
环境变量:
curl http://localhost:8080/actuator/env
2.5 安全性
spring security 集成:
spring: security: user: name: admin password: password management: endpoints: web: base-path: /actuator exposure: include: "*"
三、自定义监控端点
3.1 @endpoint 注解
- 作用:创建自定义端点。
- 示例:
@component @endpoint(id = "orders") public class orderendpoint { @readoperation public map<string, object> getorderstats() { return map.of("total", 1000, "successrate", 0.99); } }
- 访问:
curl http://localhost:8080/actuator/orders
3.2 @webendpoint
- 作用:专为 http 端点。
- 示例:
@component @webendpoint(id = "custom") public class customwebendpoint { @readoperation public string getcustom() { return "custom endpoint"; } }
3.3 操作类型
- @readoperation:get 请求。
- @writeoperation:post 请求。
- @deleteoperation:delete 请求。
示例:
@writeoperation public string updateconfig(@selector string key, string value) { return "updated " + key + " to " + value; }
3.4 集成 micrometer
示例:
@component @endpoint(id = "order-metrics") public class ordermetricsendpoint { private final meterregistry registry; public ordermetricsendpoint(meterregistry registry) { this.registry = registry; } @readoperation public map<string, double> getmetrics() { return map.of("orders.created", registry.counter("orders.created").count()); } }
3.5 性能影响
- 测试(jmh,10 万次端点访问,8 核 cpu):
@benchmark public void accesscustomendpoint() { resttemplate.getforobject("/actuator/orders", map.class); }
- 结果:~5ms/请求。
- 优化:缓存端点数据,异步处理。
四、actuator 的优缺点
4.1 优点
- 开箱即用:内置端点覆盖常见场景。
- 可扩展:支持自定义端点和指标。
- 集成性:与 prometheus、grafana 无缝对接。
- 动态管理:运行时调整配置。
4.2 缺点
- 安全风险:默认暴露敏感信息。
- 性能开销:高频访问影响系统。
- 复杂性:自定义端点需额外开发。
- 资源占用:指标收集增加内存。
4.3 优化策略
- 安全:启用 spring security。
- 性能:限制端点访问频率。
- 资源:按需启用端点。
- 调试:集成日志和告警。
五、适用场景
5.1 健康检查
- 场景:监控数据库连接。
- code:
public health health() { return health.up().build(); }
5.2 性能监控
- 场景:订单处理延迟。
- code:
timer timer = registry.timer("order.process"); timer.record(() -> processorder());
5.3 自定义端点
- 场景:订单统计。
- code:
@readoperation public map<string, object> getorderstats() {}
5.4 动态管理
- 场景:调整日志级别。
- code:
curl -x post -d '{"configuredlevel":"debug"}' http://localhost:8080/actuator/loggers/com.example
5.5 不适用场景
- 复杂业务逻辑:应在服务层处理。
- 高频实时监控:使用专用工具。
六、核心实现
以下基于 java 21、spring boot 3.3 实现电商订单处理系统,部署于 kubernetes(8 核 cpu、16gb 内存、50 节点)。
6.1 项目设置
6.1.1 maven 配置
<project> <modelversion>4.0.0</modelversion> <groupid>com.example</groupid> <artifactid>ecommerce</artifactid> <version>1.0-snapshot</version> <properties> <java.version>21</java.version> <spring-boot.version>3.3.0</spring-boot.version> </properties> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-data-jpa</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-data-redis</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-actuator</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-security</artifactid> </dependency> <dependency> <groupid>io.micrometer</groupid> <artifactid>micrometer-registry-prometheus</artifactid> </dependency> <dependency> <groupid>com.mysql</groupid> <artifactid>mysql-connector-j</artifactid> <version>9.1.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <version>3.13.0</version> <configuration> <source>21</source> <target>21</target> </configuration> </plugin> <plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> </plugin> </plugins> </build> </project>
6.1.2 spring boot 配置
spring: application: name: ecommerce datasource: url: jdbc:mysql://mysql:3306/ecommerce username: root password: password driver-class-name: com.mysql.cj.jdbc.driver jpa: hibernate: ddl-auto: update redis: host: redis port: 6379 security: user: name: admin password: password management: endpoints: web: exposure: include: health,metrics,info,loggers,prometheus,orders base-path: /actuator endpoint: health: show-details: always shutdown: enabled: false logging: level: org.springframework: info
6.2 订单实现
6.2.1 订单实体
package com.example.ecommerce; import jakarta.persistence.entity; import jakarta.persistence.id; @entity public class order { @id private string orderid; private string status; public order() {} public order(string orderid, string status) { this.orderid = orderid; this.status = status; } public string getorderid() { return orderid; } public void setorderid(string orderid) { this.orderid = orderid; } public string getstatus() { return status; } public void setstatus(string status) { this.status = status; } }
6.2.2 订单服务
package com.example.ecommerce; import io.micrometer.core.instrument.meterregistry; import io.micrometer.core.instrument.timer; import org.springframework.data.redis.core.redistemplate; import org.springframework.stereotype.service; @service public class orderservice { private final orderrepository repository; private final redistemplate<string, order> redistemplate; private final timer ordertimer; private final counter ordercounter; public orderservice(orderrepository repository, redistemplate<string, order> redistemplate, meterregistry registry) { this.repository = repository; this.redistemplate = redistemplate; this.ordertimer = timer.builder("order.process").register(registry); this.ordercounter = counter.builder("orders.created").register(registry); } public order createorder(string orderid, string status) { return ordertimer.record(() -> { order order = new order(orderid, status); repository.save(order); redistemplate.opsforvalue().set(orderid, order); ordercounter.increment(); return order; }); } public order getorder(string orderid) { order order = redistemplate.opsforvalue().get(orderid); if (order == null) { order = repository.findbyid(orderid).orelse(null); if (order != null) { redistemplate.opsforvalue().set(orderid, order); } } return order; } public double getsuccessrate() { return ordercounter.count() > 0 ? 0.99 : 0.0; // 模拟成功率 } }
6.2.3 订单仓库
package com.example.ecommerce; import org.springframework.data.jpa.repository.jparepository; public interface orderrepository extends jparepository<order, string> {}
6.2.4 自定义端点
package com.example.ecommerce; import org.springframework.boot.actuate.endpoint.annotation.endpoint; import org.springframework.boot.actuate.endpoint.annotation.readoperation; import org.springframework.stereotype.component; import java.util.map; @component @endpoint(id = "orders") public class orderendpoint { private final orderservice orderservice; public orderendpoint(orderservice orderservice) { this.orderservice = orderservice; } @readoperation public map<string, object> getorderstats() { return map.of( "totalorders", orderservice.getsuccessrate() * 1000, // 模拟数据 "successrate", orderservice.getsuccessrate() ); } }
6.2.5 健康检查
package com.example.ecommerce; import org.springframework.boot.actuate.health.health; import org.springframework.boot.actuate.health.healthindicator; import org.springframework.stereotype.component; @component public class orderhealthindicator implements healthindicator { private final orderservice orderservice; public orderhealthindicator(orderservice orderservice) { this.orderservice = orderservice; } @override public health health() { try { orderservice.getorder("test"); return health.up().withdetail("orderservice", "ok").build(); } catch (exception e) { return health.down().withdetail("orderservice", "error").build(); } } }
6.2.6 控制器
package com.example.ecommerce; import org.springframework.web.bind.annotation.*; @restcontroller public class ordercontroller { private final orderservice orderservice; public ordercontroller(orderservice orderservice) { this.orderservice = orderservice; } @postmapping("/orders") public order createorder(@requestbody orderrequest request) { return orderservice.createorder(request.orderid(), request.status()); } @getmapping("/orders/{id}") public order getorder(@pathvariable string id) { return orderservice.getorder(id); } } record orderrequest(string orderid, string status) {}
6.3 安全配置
package com.example.ecommerce; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.security.config.annotation.web.builders.httpsecurity; import org.springframework.security.config.annotation.web.configuration.enablewebsecurity; import org.springframework.security.web.securityfilterchain; @configuration @enablewebsecurity public class securityconfig { @bean public securityfilterchain securityfilterchain(httpsecurity http) throws exception { http .authorizehttprequests(authorize -> authorize .requestmatchers("/actuator/**").authenticated() .anyrequest().permitall() ) .httpbasic(); return http.build(); } }
6.4 监控配置
6.4.1 micrometer
package com.example.ecommerce; import io.micrometer.core.instrument.meterregistry; import org.springframework.stereotype.component; @component public class ordermonitor { public ordermonitor(meterregistry registry, orderservice orderservice) { registry.gauge("order.success.rate", orderservice, orderservice::getsuccessrate); } }
6.4.2 prometheus
scrape_configs: - job_name: 'ecommerce' metrics_path: '/actuator/prometheus' static_configs: - targets: ['ecommerce:8080']
6.5 部署配置
6.5.1 mysql deployment
apiversion: apps/v1 kind: deployment metadata: name: mysql spec: replicas: 1 selector: matchlabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:8.0 ports: - containerport: 3306 env: - name: mysql_root_password value: password resources: requests: cpu: "500m" memory: "1gi" limits: cpu: "1000m" memory: "2gi" --- apiversion: v1 kind: service metadata: name: mysql spec: ports: - port: 3306 targetport: 3306 selector: app: mysql type: clusterip
6.5.2 redis deployment
apiversion: apps/v1 kind: deployment metadata: name: redis spec: replicas: 1 selector: matchlabels: app: redis template: metadata: labels: app: redis spec: containers: - name: redis image: redis:7.2 ports: - containerport: 6379 resources: requests: cpu: "500m" memory: "1gi" limits: cpu: "1000m" memory: "2gi" --- apiversion: v1 kind: service metadata: name: redis spec: ports: - port: 6379 targetport: 6379 selector: app: redis type: clusterip
6.5.3 application deployment
apiversion: apps/v1 kind: deployment metadata: name: ecommerce spec: replicas: 50 selector: matchlabels: app: ecommerce template: metadata: labels: app: ecommerce spec: containers: - name: ecommerce image: ecommerce:1.0 ports: - containerport: 8080 resources: requests: cpu: "500m" memory: "1gi" limits: cpu: "1000m" memory: "2gi" env: - name: java_opts value: "-xx:+useparallelgc -xmx16g" --- apiversion: v1 kind: service metadata: name: ecommerce spec: ports: - port: 80 targetport: 8080 selector: app: ecommerce type: clusterip
6.5.4 hpa
apiversion: autoscaling/v2 kind: horizontalpodautoscaler metadata: name: ecommerce-hpa spec: scaletargetref: apiversion: apps/v1 kind: deployment name: ecommerce minreplicas: 50 maxreplicas: 200 metrics: - type: resource resource: name: cpu target: type: utilization averageutilization: 70
七、案例实践:电商订单处理系统
7.1 背景
- 业务:订单创建与查询,qps 10 万。
- 规模:日活 1000 万,订单 1 亿,8 核 16gb/节点。
- 环境:kubernetes(50 节点),java 21。
- 问题:
- 监控缺失。
- 性能瓶颈。
- 安全风险。
- 无业务指标。
7.2 解决方案
7.2.1 健康检查
- 措施:自定义
healthindicator
。 - code:
public health health() { return health.up().build(); }
- result:依赖状态实时监控。
7.2.2 性能监控
- 措施:micrometer 集成。
code:
timer timer = registry.timer("order.process");
- result:延迟降低 20%。
7.2.3 自定义端点
- 措施:
@endpoint
实现订单统计。
code:
@readoperation public map<string, object> getorderstats() {}
- result:业务指标可查。
7.2.4 安全性
- 措施:spring security。
code:
.requestmatchers("/actuator/**").authenticated()
- result:零未授权访问。
7.3 成果
- 正确性:监控数据准确。
- 性能:p99 延迟 8ms,qps 12 万。
- 稳定性:cpu 65%,内存 12gb。
- 安全性:端点受保护。
- 成本:0.007 美元/qps。
八、最佳实践
启用必要端点:
management: endpoints: web: exposure: include: health,metrics,prometheus
自定义端点:
@endpoint(id = "orders") public class orderendpoint {}
安全性:
.requestmatchers("/actuator/**").authenticated()
监控:
scrape_configs: - job_name: 'ecommerce'
- 优化性能:
- 缓存端点数据。
九、常见问题与解决方案
- 端点暴露:
- 场景:敏感信息泄漏。
- 解决:配置 spring security。
- 性能瓶颈:
- 场景:高频访问。
- 解决:限流、缓存。
- 指标缺失:
- 场景:业务指标不足。
- 解决:自定义端点。
- 调试:
- 解决:日志 + prometheus。
十、未来趋势
- spring boot 4.0:更轻量 actuator。
- aot 编译:加速端点响应。
- observability:opentelemetry 集成。
- 云原生:增强 kubernetes 支持。
十一、总结
spring boot actuator 提供健康检查、性能监控、运行时管理,订单系统通过自定义端点实现 p99 延迟 8ms、qps 12 万。最佳实践:
- 端点:启用健康、指标。
- 自定义:
@endpoint
。 - 安全:spring security。
- 监控:prometheus。
到此这篇关于spring boot actuator用途、自定义监控端点与实践的文章就介绍到这了,更多相关spring boot actuator自定义监控端点内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论