使用Spring Boot Actuator shutdown时如何让应用关闭阶段返回404?
优雅关闭阶段返回404的Actuator实现方案
完全可以通过扩展Actuator的生命周期能力实现该需求,无需引入第三方依赖。
核心逻辑:Actuator的/actuator/shutdown端点被调用时,会先发布ShutdownEndpoint.ShutdownInvokedEvent事件,该事件的发布时机早于Web服务停止、容器Bean销毁的流程,我们可以监听该事件,触发全局请求拦截逻辑,将所有新请求直接返回404,不会影响已经接收的存量请求处理。
实现步骤
- 第一步:确保已开启并暴露shutdown端点,在application配置文件中添加以下配置:
# 开启shutdown端点功能 management.endpoint.shutdown.enabled=true # web场景下暴露shutdown端点,JMX场景可忽略该配置 management.endpoints.web.exposure.include=shutdown
- 第二步:自定义最高优先级的全局过滤器,用于关闭模式触发后拦截请求返回404:
import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; // Spring Boot 2.x及以下版本替换为javax.servlet对应包 import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; @Component @Order(Ordered.HIGHEST_PRECEDENCE) public class ShutdownModeFilter extends OncePerRequestFilter { // 原子类标记位,保证多线程下状态一致 private final AtomicBoolean shutdownModeEnabled = new AtomicBoolean(false); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (shutdownModeEnabled.get()) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); return; } filterChain.doFilter(request, response); } // 触发关闭模式的方法 public void turnOnShutdownMode() { shutdownModeEnabled.set(true); } }
如果是WebFlux响应式项目,替换为WebFilter实现即可,逻辑完全一致。
- 第三步:监听Actuator的关闭事件,收到事件后开启拦截逻辑:
import org.springframework.context.ApplicationListener; import org.springframework.boot.actuate.context.ShutdownEndpoint; import org.springframework.stereotype.Component; @Component public class ShutdownEventListener implements ApplicationListener<ShutdownEndpoint.ShutdownInvokedEvent> { private final ShutdownModeFilter shutdownModeFilter; public ShutdownEventListener(ShutdownModeFilter shutdownModeFilter) { this.shutdownModeFilter = shutdownModeFilter; } @Override public void onApplicationEvent(ShutdownEndpoint.ShutdownInvokedEvent event) { // 收到关闭事件后立刻开启404拦截 shutdownModeFilter.turnOnShutdownMode(); } }
补充说明:该实现的拦截时机早于Actuator本身的端点处理逻辑,即使是其他Actuator端点在关闭模式下触发也会返回404,符合关闭阶段的访问限制要求。
内容的提问来源于stack exchange,提问作者try_harder
相关产品推荐
相关产品推荐

