springboot --自定义健康检查

参考:https://www.cnblogs.com/javanoob/p/springboot_healthcheck.html

https://www.cnblogs.com/cnblog-long/p/7245952.html

Spring Boot-Actuator 也提供了starter,为我们自动配置,在使用上我们只需要添加starter到我们的依赖中,然后启动项目即可。

       
            org.springframework.boot
            spring-boot-starter-actuator
        

常用Endpoint

Spring Boot-actuator,提供了许多有用的EndPoint,对Spring Boot应用提供各种监控,下面说一下我常用的EndPoint:

/health 应用的健康状态
/configprops 获取应用的配置信息,因为Spring Boot 可能发布时是单独的Jar包,配置文件可能包含其中, 当我们需要检查配置文件时可以使用 ConfigpropsEndPoint 进行查看一些配置是否正确。
/trace 最近几次的http请求信息

HealthEndPoint

当我们访问 http://localhost:8088/health 时,可以看到 HealthEndPoint 给我们提供默认的监控结果,包含磁盘检测和数据库检测。

{
    "status": "UP",
    "diskSpace": {
        "status": "UP",
        "total": 398458875904,
        "free": 315106918400,
        "threshold": 10485760
    },
    "db": {
        "status": "UP",
        "database": "MySQL",
        "hello": 1
    }
}

其实看 Spring Boot-actuator 源码,你会发现 HealthEndPoint 提供的信息不仅限于此,org.springframework.boot.actuate.health 包下 你会发现 ElasticsearchHealthIndicator、RedisHealthIndicator、RabbitHealthIndicator 等
也就是 HealthEndPoint 也提供 ES, Redis 等组件的健康信息。

自定义Indicator 扩展 HealthEndPoint

看源码 其实 磁盘和数据库健康信息就是 DiskSpaceHealthIndicator、DataSourceHealthIndicator 来实现的,当我们对一些我们自定义的组件进行监控时, 我们也可以实现个Indicator :

@Component
public class User implements HealthIndicator {
    /**
     * user监控 访问: http://localhost:8088/health
     *
     * @return 自定义Health监控
     */
    @Override
    public Health health() {

        // 健康检查的逻辑

        // 检查通过(方式一新建对象)
        return new Health.Builder().withDetail("usercount", 10) //自定义监控内容
                .withDetail("userstatus", "up").up().build();

        // 检查失败(方式二静态方法)
        return Health.down().withDetail("status", errorCode)
                .withDetail("message", "服务故障").build();
    }
}

这时我们再次访问: http://localhost:8088/health 这时返回的结果如下,包含了我们自定义的 User 健康信息。

{
    "status": "UP",
    "user": {
        "status": "UP",
        "usercount": 10,
        "userstatus": "up"
    },
    "diskSpace": {
        "status": "UP",
        "total": 398458875904,
        "free": 315097989120,
        "threshold": 10485760
    },
    "db": {
        "status": "UP",
        "database": "MySQL",
        "hello": 1
    }
}

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

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

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

@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);
    }
}

自定义EndPoint信息展示

其实除了扩展 HealthEndPoint 来添加一些健康检查, 我们也可以自定定义一些EndPoint 来提供程序运行时一些信息的展示:

@Configuration
public class EndPointAutoConfig {
    @Bean
    public Endpoint> customEndPoint() {
        return new SystemEndPoint();
    }
}


@ConfigurationProperties(prefix="endpoints.customsystem")
public class SystemEndPoint extends AbstractEndpoint> {

    public SystemEndPoint(){
        super("customsystem");
    }
    @Override
    public Map invoke() {
        Map result= new HashMap<>();
        Map map = System.getenv();
        result.put("username",map.get("USERNAME"));
        result.put("computername",map.get("COMPUTERNAME"));
        result.put("userdomain",map.get("USERDOMAIN"));
        return result;
    }
}

访问 http://localhost:8088/customsystem 来查看我们自定义的EndPoint ,返回结果如下:

{
    "username": "xxx",
    "userdomain": "DESKTOP-6EAN1H4",
    "computername": "DESKTOP-6EAN1H4"
}

 

你可能感兴趣的:(Springboot)