Health 信息是从 ApplicationContext 中所有的 HealthIndicator接口 的实现类 Bean 中收集的, Spring Boot 内置了一些 HealthIndicator。
内置的 HealthIndicator
在spring-boot-actuator的jar中
Name | Description |
---|---|
CassandraHealthIndicator | Checks that a Cassandra database is up. |
DiskSpaceHealthIndicator | Checks for low disk space. |
DataSourceHealthIndicator | Checks that a connection to DataSource can be obtained. |
ElasticsearchHealthIndicator | Checks that an Elasticsearch cluster is up. |
JmsHealthIndicator | Checks that a JMS broker is up. |
MailHealthIndicator | Checks that a mail server is up. |
MongoHealthIndicator | Checks that a Mongo database is up. |
RabbitHealthIndicator | Checks that a Rabbit server is up. |
RedisHealthIndicator | Checks that a Redis server is up. |
SolrHealthIndicator | Checks that a Solr server is up. |
DataSourceHealthIndicator健康检测原理
- 通过jdbcTemplate根据java.sql.Connection.getMetaData().getDatabaseProductName()获取数据库产品名,如获取到MySQL或Oracle
- 根据不同数据库,构造不同校验查询sql,如下
1
2
3
4
5// MySQL的ping
/* ping */ SELECT 1
// Oracle
SELECT 'Hello' from DUAL - 通过jdbcTemplate执行上一步构造的校验sql
- 能正常返回则说明健康。
RedisHealthIndicator健康检测原理
- 构造RedisConnection链接对象
- 如果是cluster,则调用RedisClusterConnection的clusterGetClusterInfo()方法,获取redis服务器端集群信息,并展示。
- 非集群时,通过RedisConnection的info()方法获取redis服务器端版本信息,返回并展示。
其他健康检测原理类似。。。
自定义 HealthIndicator 监控检测
一般情况下,Spring Boot 提供的健康监控无法满足我们复杂的业务场景,此时,我们就需要定制自己的 HealthIndicator, 扩展自己的业务监控。有两种方式
- 实现 HealthIndicator 接口
- 继承AbstractHealthIndicator
实现 HealthIndicator 接口
我们,实现 HealthIndicator 接口创建一个简单的检测器类。它的作用很简单,只是进行服务状态监测。此时,通过重写 health() 方法来实现健康检查。
1 | package com.fuyi.actuator.indicator; |
检测结果如下:
1 | { |
继承AbstractHealthIndicator
AbstractHealthIndicator 实现 HealthIndicator 接口,并重写了 health() 方法来实现健康检查。因此,我们只需要重写 doHealthCheck 方法即可。
一般情况下,我们不会直接实现 HealthIndicator 接口,而是继承 AbstractHealthIndicator 抽象类。因为,我们只需要重写 doHealthCheck 方法,并在这个方法中我们关注于具体的健康检测的业务逻辑服务。
- 自定义磁盘健康指示器,以G为单位检测结果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43package com.fuyi.actuator.indicator;
import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health.Builder;
import org.springframework.stereotype.Component;
@Component
public class CustDiskSpaceHealthIndicator extends AbstractHealthIndicator {
private final FileStore fileStore;
private final long thresholdBytes;
@Autowired
public CustDiskSpaceHealthIndicator(
@Value("${health.filestore.path:.}") String path,
@Value("${health.filestore.threshold.bytes:10485760}") long thresholdBytes) throws IOException {
this.fileStore = Files.getFileStore(Paths.get(path));
this.thresholdBytes = thresholdBytes;
}
@Override
protected void doHealthCheck(Builder builder) throws Exception {
long diskFreeInBytes = fileStore.getUnallocatedSpace();
if(diskFreeInBytes >= this.thresholdBytes) {
builder.up();
}
long totalSpaceInBytes = fileStore.getTotalSpace();
builder.withDetail("total", totalSpaceInBytes/1024/1024/1024 + " G");
builder.withDetail("free", diskFreeInBytes/1024/1024/1024 + " G");
builder.withDetail("threshold", this.thresholdBytes/1024/1024 + " M");
}
}
1 | { |