使用 Java 编写的程序大多是 Web 应用,通过暴露接口来提供各种各样的服务,应用程序的健康状态就看接口是否能正常调用。
考虑到健康状态检查的便捷性,即使用 HTTP 访问某个 URL 就可以知道该应用程序是否正在运行,可以使用过滤器拦截某个指定的地址,由程序直接返回健康状态。
因为 Spring Boot 的广泛使用,还可以兼容 Spring Boot 的健康检查格式,因此最后的格式就如下:
// 这里可以交给 Spring 管理public final class HealthFilter implements WebFilter {// /actuator/health 是 Spring Boot 健康检查相关的 URLprivate static final String[] FILTER_TAG = {"/actuator/health", "/health_check"};@Overridepublic 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 健康检查相关的 URLprivate static final String[] FILTER_TAG = {"/actuator/health", "/health_check"};@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic 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);}@Overridepublic void destroy() {}}
