1. Actuator 介绍
- SpringBoot Actuator 提供 http(或 JMX)端点来实现对应用程序的监视和管理、收集运行状态等功能。
引入
spring-boot-starter-actuator
可启用这些功能。<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
默认情况下,通过访问
/actuator
可以看到所有启动的端点,也可以通过配置修改这个路径地址。management.endpoints.web.base-path=/manage
2. 端点配置
- 文档:https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/htmlsingle/#production-ready-endpoints
SpringBoot 包含许多内置端点,允许添加自己的端点,可以配置端点是否对外开放或关闭。
http 配置
- 通过 http 公开除了 env 和 beans 端点之外的所有内容
management.endpoints.web.exposure.include="*" management.endpoints.web.exposure.exclude=env,beans
- 通过 http 公开除了 env 和 beans 端点之外的所有内容
CORS 跨域支持(默认情况下禁用 CORS 支持)
management.endpoints.cors.allowed-origins=http://example.com management.endpoints.cors.allowed-methods=GET,POST
修改 ManagerServer 服务器配置
management.server.port=8081 #如果设置为-1代表禁用http端点 management.server.address=127.0.0.1
- 访问
/actuator/health
查看程序中组件检查项的运行情况信息,在出现故障时能及时发现。 - SpringBoot 默认提供了对 Redis、RabbitMQ、DataSource、MongoDB 等组件的检查项。
展示更详细内容(默认 never)
management.endpoint.health.show-details=never(或者 when-authorized|always)
返回结果
- 如果有检查项处于非检查状态,http 状态码为 503,返回值为 DOWN 或者 OUT_OF_SERVICE。
- 如果没有检查出问题,返回 http 状态码为 200,返回值 UP 或者 UNKNOWN
自定义检查项
实现
HealthIndicator
接口,通过 spring 实例化一个对象,SpringBoot 会自动触发健康检查,并归入 health 的结果。@Component public class MyHealthCheck1 implements HealthIndicator { public Health health() { int i = new Random().nextInt(); if (i % 2 == 0) { return Health.up().withDetail("细节", "1").build(); } else { return Health.down().withDetail("细节", "2").build(); } } }
或者继承 AbstractHealthIndicator 类,实现 doHealthCheck() 方法
@Component public class MyHealthCheck2 extends AbstractHealthIndicator { @Override protected void doHealthCheck(Health.Builder builder) throws Exception { int i = new Random().nextInt(); if (i % 2 == 0) { builder.withDetail("细节", "1").up(); } else { builder.withDetail("细节", "2").down(); } } }
5. 端点讲解 - 日志配置
SpringBoot 日志配置
logging.level.root=WARN logging.level.org.springframework.web=DEBUG logging.level.org.hibernate=ERROR
通过
/actuator/loggers
查看日志配置- 运行时修改配置
curl -XPOST -H 'Content-Type: application/json' -i 'http://127.0.0.1:8081/manage/loggers/ROOT' --data '{ "configuredLevel": "DEBUG" }'
6. 端点讲解 - metrics
https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/htmlsingle/#production-ready-metrics
- metrics 是生产应用中很重要的功能,简单可理解为对运行时具体功能的监控。SpringBoot 中集成了 micrometer 实现。
- 支持查看哪些数据?
- 通过
/actuator/metrics
查看所有支持的信息,/metrics/requiredMetircName
查看指定某一项指标。 - JVM 内存、线程、GC 信息、类加载情况、CPU 指标、Http 请求统计、Tomcat 信息…..。
- 通过
- 与监控系统的集成
- 支持将数据导出到:AppOptics、Atlas、Datadog、Dynatrace、Elastic、Ganglia、Graphite、Humio、Influx、JMX、KairosDB、New Relic、Prometheus、SignalFx、Simple(in-memory)、Stackdriver、StatsD、Wavefront。
自定义监控指标
代码中注入
MeterRegistry
对象,然后进行手动注册。@Component public class MyMetrics { private final List<String> words = new CopyOnWriteArrayList<String>(); public MyMetrics(MeterRegistry meterRegistry) { meterRegistry.gaugeCollectionSize("dictionary.size", Tags.empty(), this.words); } }
7. 自定义端点
- 可以理解为“概念上类似 SpringMVC 的 controller 写法,却又是完全不同的一套 API。”。
- 端点定义:@Endpoint 或 @WebEndpoint 或 @JmxEndpoint。
- 端点操作:@ReadOperation、@WriteOperation、@DeleteOperation。
- 参数接收:web 环境下添加 @Selector。
@Endpoint(id = "myEndPoint")
@Component
public class MyEndpoint {
String name = "default";
@ReadOperation
public String getName() {
return "{\"name\":\"" + name + "\"}";
}
@DeleteOperation
public void delName() {
name = "";
}
@WriteOperation
public void setName(@Selector String arg0) {
this.name = arg0;
}
}
curl -XGET http://localhost:8090/actuator/myEndPoint
curl -XPOST http://localhost:8090/actuator/myEndPoint/12345677889
curl -XDELETE http://localhost:8090/actuator/myEndPoint
8. 快速理解 JMX 机制
- Java Management Extensions(JMX)提供了一种监视和管理应用程序的标准机制。
- tomcat、kafka、druid 都是用的 JMX 技术来实现对外暴露管理接口和监控信息。
- Jconsole 工具如何通过 JMX 技术实现对应用的监控和管理?
- 通过 Spring 框架快速增加自定义 MBean。
- 默认情况下,SpringBoot 将管理端点公开为 org.springframework.boot 域下的 JMX MBean。
- 通过 JMX 公开所有端点并仅显示 health 和 info 端点。
management.endpoints.jmx.exposure.exclude=* management.endpoints.jmx.exposure.include=info,health
public interface JmxMBean {
public String getName();
public void setName(String name);
public String printHello();
public String printHello(String whoName);
}
@ManagedResource
public class JmxTest implements JmxMBean {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String printHello() { return "JmxTest " + name; }
public String printHello(String whoName) { return "JmxTest " + whoName; }
}
// 注册定义自己的 MBean
public class TestJMXRegListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
JmxTest jmxTest;
public void onApplicationEvent(ContextRefreshedEvent event) {
try {
// create mbean server
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
// create object name
ObjectName objectName = null;
objectName = new ObjectName("jmxBean:name=testJMX");
// 注册
server.registerMBean(jmxTest, objectName);
/**
* JMXConnectorServer server
* 这句话非常重要,不能缺少!注册一个端口,绑定 url 后,客户端就可以使用 rmi 通过 url 方式来连接 JMXConnectorServer
*/
Registry registry = LocateRegistry.createRegistry(1099);
// 构造 JMXServiceURL
JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
// 构建 JMXConnectorServer
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, server);
// 启动
cs.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}