使用 Java 编写的程序大多是 Web 应用,通过暴露接口来提供各种各样的服务,应用程序的健康状态就看接口是否能正常调用。

    考虑到健康状态检查的便捷性,即使用 HTTP 访问某个 URL 就可以知道该应用程序是否正在运行,可以使用过滤器拦截某个指定的地址,由程序直接返回健康状态。

    因为 Spring Boot 的广泛使用,还可以兼容 Spring Boot 的健康检查格式,因此最后的格式就如下:

    1. // 这里可以交给 Spring 管理
    2. public final class HealthFilter implements WebFilter {
    3. // /actuator/health 是 Spring Boot 健康检查相关的 URL
    4. private static final String[] FILTER_TAG = {"/actuator/health", "/health_check"};
    5. @Override
    6. public Mono<Void> filter(@Nullable final ServerWebExchange exchange, @Nullable final WebFilterChain chain) {
    7. ServerHttpRequest request = Objects.requireNonNull(exchange).getRequest();
    8. String urlPath = request.getURI().getPath();
    9. for (String check : FILTER_TAG) {
    10. if (check.equals(urlPath)) {
    11. // 返回 Health 的 JSON 字符串
    12. String result = JsonUtils.toJson(new Health.Builder().up().build());
    13. DataBuffer dataBuffer = exchange.getResponse().bufferFactory().wrap(result.getBytes());
    14. return exchange.getResponse().writeWith(Mono.just(dataBuffer));
    15. }
    16. }
    17. return Objects.requireNonNull(chain).filter(exchange);
    18. }
    19. }

    如果是 Spring Boot 低版本,非响应式编程,代码格式如下:

    1. @Configuration
    2. @WebFilter(urlPatterns = "/*")
    3. public class HealthFilter implements Filter {
    4. // /actuator/health 是 Spring Boot 健康检查相关的 URL
    5. private static final String[] FILTER_TAG = {"/actuator/health", "/health_check"};
    6. @Override
    7. public void init(FilterConfig filterConfig) throws ServletException {
    8. }
    9. @Override
    10. public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
    11. String urlPath = ((HttpServletRequest) request).getServletPath();
    12. for (String tag : FILTER_TAG) {
    13. if (tag.equals(urlPath)) {
    14. // 返回 Health 的 JSON 字符串
    15. String res = JSON.toJSONString(new Health.Builder().up().build());
    16. response.getWriter().write(res);
    17. return;
    18. }
    19. }
    20. chain.doFilter(request, response);
    21. }
    22. @Override
    23. public void destroy() {
    24. }
    25. }