当我们编写的项目上线后,为了能第一时间知晓该项目是否出现问题,常常对项目进行健康检查及一些指标进行监控。

    cloudopt-next-health 就是一个帮助做健康检查的插件。

    我们来看个简单的例子:

    1. fun main() {
    2. HealthChecksManager.register("disk", DiskSpaceHealthIndicator())
    3. HealthChecksManager.register("jvm", JvmHealthIndicator())
    4. HealthChecksManager.register("system", SystemIndicator())
    5. HealthChecksManager.registerHook("logger", LoggerHook())
    6. NextServer.addPlugin(HealthChecksPlugin())
    7. NextServer.run()
    8. }

    你需要先使用 HealthChecksManager.register 注册需要的健康检查器,第一个参数为自定义的名称,第二个参数为检查器。你还可以使用 registerHook 注册健康检查的回调。

    cloudopt-next-health 默认带了 DiskSpaceHealthIndicator、JvmHealthIndicator、SystemIndicator 分别是硬盘空间、Jvm 信息、系统信息三项检查器。以及默认的 LoggerHook 日志回调。

    其它部分 Next 的插件也带了自身的健康检查器,可以注册进去,具体见各个插件的文档。

    接着你需要修改配置文件,加上 healthChecks 这一项。

    1. {
    2. "packageName": "net.cloudopt.next.health.test",
    3. "port": 8080,
    4. "healthChecks": {
    5. "applicationName": "demo",
    6. "password": "1234",
    7. "intervalTime": 5000,
    8. "accessPath": "/health"
    9. }
    10. }

    你可以通过 applicationName 修改健康检查结果时的名字,也可以通过 password 设置访问时必须要带的密码参数的值(如果为空白字符串不需要密码),intervalTime 可以设置健康检查的间隔时间,accessPath 可以设置健康检查的路径。

    启动后访问 http://127.0.0.1:8080/health?password=1234 你就可以看到下面这样的页面:

    Snipaste_2021-05-20_16-53-32.png

    根据 intervalTime 的值,每 5s 更新一次。

    想要实现自定义的健康检查器也非常简单,你可以声明任意类并实现 HealthIndicator 接口即可。我们来看下 SystemIndicator 检查器的例子:

    1. class SystemIndicator : HealthIndicator {
    2. override suspend fun checkHealth(): HealthChecksResult {
    3. return await {
    4. val mxBean: OperatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean()
    5. return@await HealthChecksResult(
    6. data = mutableMapOf(
    7. "name" to mxBean.name,
    8. "arch" to mxBean.arch,
    9. "availableProcessors" to mxBean.availableProcessors,
    10. "version" to mxBean.version
    11. )
    12. )
    13. }
    14. }
    15. }

    你还可以在检查的时候通过返回的 HealthChecksResult 的 status 的值来修改健康检查结果的 status。

    想要实现自定义的 Hook 的话,也只需要实现 HealthChecksHook 即可。Hook 一般适用于通知、修改状态等等。如你们公司要求硬盘涨到 80% 以上的时候就应该发出邮件警报,那么可以声明一个邮件警报的 Hook。我们看下自带的日志 Hook 是如何实现的:

    1. class LoggerHook : HealthChecksHook {
    2. private val logger = Logger.Companion.getLogger(this::class)
    3. override suspend fun hook(healthChecksReport: MutableMap<String, Any>) {
    4. logger.info(healthChecksReport.toJsonString())
    5. }
    6. }

    healthChecksReport 其实就是跟直接访问看到的是基本一致的。是汇总了各个检查器的 HealthChecksResult 的 map。