Spring Boot自定义健康检查指示器

x33g5p2x  于2022-10-18 转载在 Spring  
字(4.7k)|赞(0)|评价(0)|浏览(647)

在本文中,我们将学习如何为Spring Boot应用程序编写自定义健康检查指示器。
Spring Boot开箱即用的健康检查很好。但在现实世界中,通常情况下,一个应用程序依赖于其他应用程序的可用性来执行操作。在这种情况下,为下游系统添加健康指示器将很有帮助,就像数据库或文件系统健康检查一样。SpringBoot有一种干净、简单的方法来实现这一点,我们将在本文中找到方法。
让我们看一个真实的场景。

  • 您正在为您的网站开发订单处理系统。
  • 您的订单服务使用第三方的付款服务。
  • 如果付款服务停止,您的订单服务将无法处理请求
  • 客户无法直接测试支付服务是否启动

在这种情况下,如果支付系统关闭,最好将订单服务标记为关闭。下面是方法。

健康指示器类

在进一步讨论之前,我希望您阅读有关Spring引导健康检查指示器的信息,因为这样您可以更好地理解HealthIndicators
Spring Boot健康检查指示器由HealthIndicator接口的自动配置bean控制。如果愿意,我们可以编写自己的HealthIndicator bean。
例如,检查这个bean定义。

package com.springhow.examples.customhealthchecks;

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class CustomHealthIndicator implements HealthIndicator {
    
    @Override
    public Health health() {
        return Health.up().build();
    }

}
Code language: CSS (css)

上面的定义创建了一个名为customHealthIndicator的bean,将由AutoConfiguredHealthContributorRegistry选择http://localhost:8080/actuator/health

$ curl  -s -i -X GET http://localhost:8080/actuator/health

HTTP/1.1 200 
Content-Type: application/vnd.spring-boot.actuator.v3+json
Transfer-Encoding: chunked
Date: Sat, 01 Aug 2020 19:03:38 GMT
Keep-Alive: timeout=60
Connection: keep-alive

{
  "status": "UP",
  "components": {
    "custom": {
      "status": "UP"
    },
    "diskSpace": {
      "status": "UP",
      "details": {
        "total": 254971625472,
        "free": 60132696064,
        "threshold": 10485760,
        "exists": true
      }
    },
    "ping": {
      "status": "UP"
    }
  }
}
Code language: JavaScript (javascript)

我们示例中的public Health health()方法只是构建一个状态UP响应。但您也可以发送以下任何一个状态响应。

  • Status.UP
  • Status.DOWN
  • Status.OUT_OF_SERVICE
  • Status.UNKNOWN

自定义健康检查名称

注意,健康组件的名称基于Bean的类名。这是因为健康端点需要一个唯一的名称来显示响应中的新组件。
因此,HealthContributorNameFactory接受指示符bean名称,并根据需要从bean名称中去掉后缀healthindicatorhealthcontributor。在我们的例子中,custom表示bean customHealthIndicator
如果我们想重命名健康检查,我们要么需要以不同的方式命名类,要么只给组件定义一个如下的名称。

package com.springhow.examples.customhealthchecks;

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component("downstream")
public class CustomHealthIndicator implements HealthIndicator {
    
    @Override
    public Health health() {
        return Health.up().build();
    }

}
Code language: CSS (css)

这将创建相同的响应,但健康组件的名称将为downstream

第三方服务的自定义运行状况检查

为了模拟第三方API,我将使用mocky.io。它可以是生成HTTP 200 OK响应的任何URL。
让我们将以下属性添加到application.properties

my.downstream.service.url = https://run.mocky.io/v3/ed8d9ae2-7d0d-4411-8b8c-66106d8a2721
Code language: JavaScript (javascript)

此示例URL给出以下响应。

$ curl  -s -i -X GET https://run.mocky.io/v3/ed8d9ae2-7d0d-4411-8b8c-66106d8a2721

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Date: Sat, 01 Aug 2020 19:51:34 GMT
Content-Length: 21

{
  "status": "OK"
}
Code language: JavaScript (javascript)

因此,让我们为CustomHealthIndicator添加一些逻辑,以验证HTTP状态代码和响应的状态文本。

@Component("downstream")
public class CustomHealthIndicator implements HealthIndicator {

    @Value("${my.downstream.service.url}")
    private String downstreamUrl;

    RestTemplate restTemplate = new RestTemplate();

    @Override
    public Health health() {
        try {
            ResponseEntity<JsonNode> responseEntity
                    = restTemplate.getForEntity(downstreamUrl, JsonNode.class);
            if (responseEntity.getStatusCode().is2xxSuccessful()) {
                String status = responseEntity.getBody().get("status").textValue();
                if (status.equals("OK")) {
                    return Health.up().withDetail("status", status).build();
                } else {
                    return Health.down().build();
                }
            } else {
                return Health.down().build();
            }
        } catch (Exception e) {
            return Health.down().withException(e).build();
        }
    }
}
Code language: JavaScript (javascript)

让我们给出一个URL,它将给出503 Service unavailable状态。

my.downstream.service.url = https://run.mocky.io/v3/1caa3162-845f-4b98-9e26-1fb90d23d970
Code language: JavaScript (javascript)

由于此URL发出503 service unavailable错误,restTemplate抛出一个HttpServerErrorException,然后将其捕获并用于使用withException()构建器方法返回健康信息。
在本例中,示例响应如下所示。

GET http://localhost:8080/actuator/health

HTTP/1.1 200 
Content-Type: application/vnd.spring-boot.actuator.v3+json
Transfer-Encoding: chunked
Date: Sat, 01 Aug 2020 20:08:28 GMT
Keep-Alive: timeout=60
Connection: keep-alive

{
  "status": "UP",
  "components": {
    "diskSpace": {
      "status": "UP",
      "details": {
        "total": 254971625472,
        "free": 61228318720,
        "threshold": 10485760,
        "exists": true
      }
    },
    "downstream": {
      "status": "UNKNOWN",
      "details": {
        "error": "org.springframework.web.client.HttpServerErrorException$ServiceUnavailable: 503 Service Unavailable: [{\n  \"status\": \"Not OK\"\n}]"
      }
    },
    "ping": {
      "status": "UP"
    }
  }
}
Code language: JavaScript (javascript)

this GitHub repository中提供了这些示例。

相关文章

微信公众号

最新文章

更多