You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K8s部署SpringBoot服务Pod滚动更新时请求丢失报BeanCreationNotAllowedException

报错信息:org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'controller': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)

问题根因

该异常本质是Kubernetes Pod终止流程和Spring上下文销毁流程时序不匹配导致:

  1. K8s触发Pod终止时,服务端点摘除是异步操作,最多需要数秒才能完成全集群路由规则更新,这段时间仍有新请求转发到待终止Pod
  2. Spring上下文提前启动销毁流程,正在处理/新进入的请求尝试获取Bean时,Singleton Bean工厂已进入销毁阶段,触发对应异常,最终导致请求丢失
修复方案
  • 配置K8s Pod终止时序适配
    调整Pod的YAML配置,增加preStop钩子和合理的终止宽限期,确保路由规则更新完成后再启动Spring停机流程:

    spec:
      terminationGracePeriodSeconds: 45 # 需大于Spring优雅停机的等待时长
      containers:
      - name: 你的服务容器名
        lifecycle:
          preStop:
            exec:
              command: ["sh", "-c", "sleep 15"] # 时长可根据集群路由更新耗时调整,一般5-20秒即可
        # 原有livenessProbe、readinessProbe配置保留,可适当调大livenessProbe的failureThreshold避免滚动更新时误判
    
  • 开启Spring优雅停机
    你使用的SpringBoot 2.1.5版本无内置优雅停机配置,建议优先升级到SpringBoot 2.3.x+稳定兼容版本,添加如下配置即可:

    server:
      shutdown: graceful
    spring:
      lifecycle:
        timeout-per-shutdown-phase: 30s # 根据业务最长请求耗时调整,保证所有在途请求处理完成再销毁上下文
    

    若暂时无法升级SpringBoot版本,可自定义Tomcat连接器停机逻辑:实现TomcatConnectorCustomizer接口,在停机时先暂停连接器接收新请求,等待现有请求处理完成再继续销毁流程。

  • 清理不合理的Bean销毁逻辑
    检查代码中所有带@PreDestroy注解的销毁方法、自定义的Bean销毁回调,禁止在销毁逻辑中主动调用getBean()触发新的Bean实例创建;如果存在异步处理逻辑,需配置线程池的awaitTerminationSeconds参数,保证停机时等待异步任务执行完成。

  • 版本兼容性优化
    Java 12属于非LTS版本,SpringBoot 2.1.5对该版本的生命周期处理存在已知兼容问题,建议降级到Java 11 LTS版本,可避免大量JDK和框架适配问题。

效果验证

滚动更新发布调整后的配置,在发布期间持续发送请求统计成功率,同时检查服务日志不再出现BeanCreationNotAllowedException异常即可确认修复完成。

内容的提问来源于stack exchange,提问作者Pankaj Garg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 13:39:01