Spring Boot 揭秘与实战(九) 应用监控篇 - HTTP 健康监控

3,244 阅读2分钟

Health 信息是从 ApplicationContext 中所有的 HealthIndicator 的 Bean 中收集的, Spring Boot 内置了一些 HealthIndicator。

博客地址:blog.720ui.com/

内置 HealthIndicator 监控检测

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.

我们,来看下源代码清单。

可见,Spring Boot 帮忙我们集成了许多比较常见的健康监控,例如 MySQL、 MongoDB、 Redis、 ElasticSearch、 Solr、 RabbitMQ 等。

自定义 HealthIndicator 监控检测

一般情况下,Spring Boot 提供的健康监控无法满足我们复杂的业务场景,此时,我们就需要定制自己的 HealthIndicator, 扩展自己的业务监控。

我们,实现 HealthIndicator 接口创建一个简单的检测器类。它的作用很简单,只是进行服务状态监测。此时,通过重写 health() 方法来实现健康检查。

@Component
public class CusStatusHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        int errorCode = check(); 
        if (errorCode != 0) {
            return Health.down()
                    .withDetail("status", errorCode)
                    .withDetail("message", "服务故障")
                    .build();
        }
        return Health.up().build();
    }

    private int check(){
        // 对监控对象的检测操作  
        return HttpStatus.NOT_FOUND.value();
    }
}

我们,来看看打印结果。

{
  "status": "DOWN",
  "cusStatus": {
    "status": 404,
    "message": "服务故障"
  }
}

此外,我们还可以通过继承 AbstractHealthIndicator 类,创建一个检测器类。

@Component
public class CusDiskSpaceHealthIndicator extends AbstractHealthIndicator {

    private final FileStore fileStore;
    private final long thresholdBytes;

    @Autowired
    public CusDiskSpaceHealthIndicator(
            @Value("${health.filestore.path:/}") String path,
            @Value("${health.filestore.threshold.bytes:10485760}") long thresholdBytes) 
                    throws IOException {
        fileStore = Files.getFileStore(Paths.get(path));
        this.thresholdBytes = thresholdBytes;
    }

    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        long diskFreeInBytes = fileStore.getUnallocatedSpace();
        if (diskFreeInBytes >= thresholdBytes) {
            builder.up();
        } else {
            builder.down();
        }

        long totalSpaceInBytes = fileStore.getTotalSpace();
        builder.withDetail("disk.free", diskFreeInBytes);
        builder.withDetail("disk.total", totalSpaceInBytes);
    }
}

AbstractHealthIndicator 实现 HealthIndicator 接口,并重写了 health() 方法来实现健康检查。因此,我们只需要重写 doHealthCheck 方法即可。

一般情况下,我们不会直接实现 HealthIndicator 接口,而是继承 AbstractHealthIndicator 抽象类。因为,我们只需要重写 doHealthCheck 方法,并在这个方法中我们关注于具体的健康检测的业务逻辑服务。

我们,来看看打印结果。

{
  "status": "UP",
  "cusDiskSpace": {
    "status": "UP",
    "disk.free": 79479193600,
    "disk.total": 104856547328
  }
}

源代码

相关示例完整代码: springboot-action

(完)

更多精彩文章,尽在「服务端思维」微信公众号!