使用 Java 编写的程序大多是 Web 应用,通过暴露接口来提供各种各样的服务,应用程序的健康状态就看接口是否能正常调用。
考虑到健康状态检查的便捷性,即使用 HTTP 访问某个 URL 就可以知道该应用程序是否正在运行,可以使用过滤器拦截某个指定的地址,由程序直接返回健康状态。
因为 Spring Boot 的广泛使用,还可以兼容 Spring Boot 的健康检查格式,因此最后的格式就如下:
// 这里可以交给 Spring 管理
public final class HealthFilter implements WebFilter {
// /actuator/health 是 Spring Boot 健康检查相关的 URL
private static final String[] FILTER_TAG = {"/actuator/health", "/health_check"};
@Override
public Mono<Void> filter(@Nullable final ServerWebExchange exchange, @Nullable final WebFilterChain chain) {
ServerHttpRequest request = Objects.requireNonNull(exchange).getRequest();
String urlPath = request.getURI().getPath();
for (String check : FILTER_TAG) {
if (check.equals(urlPath)) {
// 返回 Health 的 JSON 字符串
String result = JsonUtils.toJson(new Health.Builder().up().build());
DataBuffer dataBuffer = exchange.getResponse().bufferFactory().wrap(result.getBytes());
return exchange.getResponse().writeWith(Mono.just(dataBuffer));
}
}
return Objects.requireNonNull(chain).filter(exchange);
}
}
如果是 Spring Boot 低版本,非响应式编程,代码格式如下:
@Configuration
@WebFilter(urlPatterns = "/*")
public class HealthFilter implements Filter {
// /actuator/health 是 Spring Boot 健康检查相关的 URL
private static final String[] FILTER_TAG = {"/actuator/health", "/health_check"};
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
String urlPath = ((HttpServletRequest) request).getServletPath();
for (String tag : FILTER_TAG) {
if (tag.equals(urlPath)) {
// 返回 Health 的 JSON 字符串
String res = JSON.toJSONString(new Health.Builder().up().build());
response.getWriter().write(res);
return;
}
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}