Spring Boot 1.0 Web服务优雅下线

探讨了在SpringBoot环境下,如何实现Web服务的优雅下线,即在停止接收新请求的同时,确保已接收请求得到妥善处理。文章对比了三种方案,包括使用SpringApplication.exit方法、调用spring-boot-actuator的shutdown端点,以及利用undertow的GracefulShutdownHandler类。最终指出,结合方案三与其他方案可实现真正的优雅下线。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring Boot 1.0 Web服务优雅下线

Web服务优雅下线定义

  1. 停止接收新的服务
  2. 已经接收的请求正常处理并返回
  3. 停止应用

环境约束

  • Spring Boot 1.5.9.RELEASE
  • undertow 1.4.21.Final

实现方案

方案一,使用SpringApplication.exit(applicationContext)方法
方案二,调用spring-boot-actuator的shutdown端点
方案三,利用undertow的GracefulShutdownHandler类的shutdown方法

结论

直接使用方案一、方案二不能实现“Web服务优雅下线定义”的第2点,不能实现优雅下线。先实现方案三,再利用方案一或方案二可以实现优雅下线。

方案一,使用SpringApplication.exit(applicationContext)方法

这个方法其实封装的是ApplicationContext的close方法,支持自定义exitCode,并且在关闭前会发布ExitCodeEvent事件。

方案二,调用spring-boot-actuator的shutdown端点

启用shutdown端点需要如下配置:

  1. pom文件引入spring-boot-starter-actuator
  2. bootstrap.yml或application.yml增加
    management:
      security:
        enabled: false
    endpoints:
      shutdown:
        enabled: true

shutdown端点也是利用ApplicationContext的close方法实现停止应用。具体源码见org.springframework.boot.actuate.endpoint.ShutdownEndpoint#invoke

方案三,利用undertow的GracefulShutdownHandler类的shutdown方法

前面2种方案会直接停止应用,导致已经接收的请求不能正确处理并返回;Spring Boot没有提供现成的方法优雅地停止Web服务,但我们可以利用undertow提供的机制和GracefulShutdownHandler来实现undertow这一Web服务的优雅下线。自定义代码如下,

    @Bean
    public GracefulShutdownUndertow GracefulUndertowShutdown() {
        return new GracefulShutdownUndertow();
    }

    @Bean
    public UndertowEmbeddedServletContainerFactory servletWebServerFactory(GracefulShutdownUndertow gracefulShutdownUndertow) {
        UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
        factory.addDeploymentInfoCustomizers(deploymentInfo -> deploymentInfo.addInitialHandlerChainWrapper(gracefulShutdownUndertow));
        return factory;
    }

    private static class GracefulShutdownUndertow implements ApplicationListener<ContextClosedEvent>, HandlerWrapper {

        private volatile GracefulShutdownHandler handler;

        @Override
        public void onApplicationEvent(ContextClosedEvent contextClosedEvent){
            try{
                this.handler.shutdown();
                this.handler.awaitShutdown(30000);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        @Override
        public HttpHandler wrap(HttpHandler httpHandler) {
            this.handler = new GracefulShutdownHandler(httpHandler);
            return this.handler;
        }
    }

原理:undertow的WEB容器由UndertowEmbeddedServletContainerFactory负责创建。我们通过自定义UndertowEmbeddedServletContainerFactory这个Bean,向其中增加GracefulShutdownHandler;这样在应用停止时,GracefulShutdownUndertow收到ContextClosedEvent事件,触发GracefulShutdownHandler的shutdown方法,实现undertow容器的正常关闭,进而实现整个服务优雅下线。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值