问题描述

今天线上sentry报出

java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@73ba6fe6 has been closed alreadyat org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1071)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1092)at xxxxxxxxxat xxxxxxxxxat com.alibaba.dubbo.common.bytecode.Wrapper21.invokeMethod(Wrapper21.java)at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47)at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:76)at com.alibaba.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:52)at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56)at com.alibaba.dubbo.validation.filter.ValidationFilter.invoke(ValidationFilter.java:58)at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at com.alibaba.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:62)at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at xxxxxxxxxat com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:75)at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at com.alibaba.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:42)at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at com.alibaba.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:78)at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at xxxxxxxxxat com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at com.alibaba.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:73)at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at com.alibaba.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:138)at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at com.alibaba.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38)at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at com.alibaba.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:38)at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at xxxxxxxxat com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:104)at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:96)at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:173)at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51)at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)

根据面向百度编程的原则,先网上找了找什么原因,但是查到的没什么相关的,StackOverflow搜到了相同的报错但是场景好像跟我们不太一样。没办法看看异常栈里面说了啥。
根据最后两行找到报错代码块

protected void assertBeanFactoryActive() {if (!this.active.get()) {if (this.closed.get()) {throw new IllegalStateException(getDisplayName() + " has been closed already");}else {throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");}}}

可以大概看出来错误大概是这里抛出来的,然后看看做了什么判断。
首先判断了active状态
从idea的调用提示可以看出来,这个active大概被这些地方赋值和调用了。
看了一下赋值部分

protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);if (logger.isInfoEnabled()) {logger.info("Refreshing " + this);}// Initialize any placeholder property sources in the context environment.initPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredPropertiesgetEnvironment().validateRequiredProperties();// Store pre-refresh ApplicationListeners...if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);}else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Allow for the collection of early ApplicationEvents,// to be published once the multicaster is available...this.earlyApplicationEvents = new LinkedHashSet<>();}

大概通过方法名可以看出来这个方法主要是在做容器初始化的一些准备,并将active设置为true。

protected void cancelRefresh(BeansException ex) {this.active.set(false);}

这个方法是在容器执行初始化时catch到了异常,将active值置为false,之后抛出异常。
调用如下

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}}

另外一个赋值的地方就是在容器执行关闭方法的时候。

protected void doClose() {// Check whether an actual close attempt is necessary...if (this.active.get() && this.closed.compareAndSet(false, true)) {if (logger.isInfoEnabled()) {logger.info("Closing " + this);}LiveBeansView.unregisterApplicationContext(this);try {// Publish shutdown event.publishEvent(new ContextClosedEvent(this));}catch (Throwable ex) {logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);}// Stop all Lifecycle beans, to avoid delays during individual destruction.if (this.lifecycleProcessor != null) {try {this.lifecycleProcessor.onClose();}catch (Throwable ex) {logger.warn("Exception thrown from LifecycleProcessor on context close", ex);}}// Destroy all cached singletons in the context's BeanFactory.destroyBeans();// Close the state of this context itself.closeBeanFactory();// Let subclasses do some final clean-up if they wish...onClose();// Reset local application listeners to pre-refresh state.if (this.earlyApplicationListeners != null) {this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Switch to inactive.this.active.set(false);}}

然后我们看下第二个判断条件close字段。

可以看出只有2个地方赋值
一个是在上面prepareRefresh()方法中,设置为false;(容器刚准备初始化,肯定设置为false)
第二个地方也是上面doClose()方法,如果active为true,那么就通过CAS操作将close置为true。
所以能打印出如下异常,肯定就是执行了doClose方法。

org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@73ba6fe6 has been closed already

综上,结合sentry报错的请求路径以及服务器ip,初步认为是k8s容器正在销毁,内部的服务准备关闭的时候nginx仍然把请求分发到该pod,导致出现该报错。然后查看k8s该服务pod列表,并没有找到ip,应该就是在报错之后销毁了。
目前这些是基于上面的报错以及部分spring源码推测,还没做测试。如果哪里说的有问题,欢迎评论指出哈。

更新—后来又看了一下,这里是一个web服务调用dubbo服务,然后此时dubbo服务进行了缩容,并且目前没有支持dubbo的优雅停机,导致接收到了请求但是dubbo服务容器和pod正在关闭,最终导致了这个错误。

IllegalStateException:AnnotationConfigServletWebServerApplicationContext@73ba6fe6 has been closed相关推荐

  1. java 数据库 流式查询_关于mybatis:强大MyBatis-三种流式查询方法

    基本概念 流式查问指的是查问胜利后不是返回一个汇合而是返回一个迭代器,利用每次从迭代器取一条查问后果.流式查问的益处是可能升高内存应用. [腾讯云]云产品限时秒杀,爆款1核2G云服务器,首年99元 如 ...

  2. 还在用分页?你out了 !试试 MyBatis 流式查询,真心强大!

    欢迎关注方志朋的博客,回复"666"获面试宝典 基本概念 流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果.流式查询的好处是能够降低内存使 ...

  3. 还在用分页?太Low !试试 MyBatis 流式查询,真心强大!

    以下文章来源方志朋的博客,回复"666"获面试宝典 基本概念 流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果.流式查询的好处是能够降低内 ...

  4. 强大:MyBatis 流式查询

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! ‍基本概念 流式查询指的是查询成功后不是返回一个集合而是返 ...

  5. 新技能 MyBatis 千万数据表,快速分页!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:https://segmentfault.com/a ...

  6. MyBatis千万级数据查询解决方案,避免OOM

    流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果.流式查询的好处是能够降低内存使用. 如果没有流式查询,我们想要从数据库取 1000 万条记录而又没有足够的内 ...

  7. jboss学习 - vfs---转载

    jboss的VFS是为了解决什么问题,他为什么有用呢 在jboss中有很多类似的资源操作的代码都分散在程序的各个地方,大多数情况下代码首先确定操作的资源的类型,比如是文件或者是文件夹,通过URL加载的 ...

  8. java中hasnext的作用_java中Scanner的hasNext()的疑问

    第一个问题,两段代码的区别在于阻塞的位置不同,加上一行输出代码就可以很明显地看到差别. Test.java import java.util.Scanner; public class Test { ...

  9. mybatis删除成功返回0_你还在用分页?试试 MyBatis 流式查询,真心强大!

    转自:捏造的信仰 segmentfault.com/a/1190000022478915 基本概念 流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果.流式查询 ...

最新文章

  1. 第十五届全国大学生智能车线上比赛流程规范总结
  2. 《大话设计模式》6个原则 转帖
  3. 单片机中通用的类型别名
  4. 下面是html5中新增的结构元素的是,HTML5的新的结构元素介绍
  5. maven常用插件配置
  6. mysql数据库合并游戏合服_浅谈滚服游戏如果实现一键合服
  7. 蓝桥杯历年真题及答案汇总整理(Java、C语言、Python)
  8. python怎么开服务器,实战讲解:如何用Python搭建一个服务器
  9. 微信开发errcode:40125
  10. android拦截彩信,Android手机恶意彩信拦截系统的设计和实现
  11. 要只看每日减少的新增数量,别忘了疫情最开始的时候可能也只有几个人患病
  12. Packet(信息包)
  13. 2018数据结构课程设计报告
  14. 试一试 kolla部署OpenStack Ocata
  15. 2020年B证(安全员)考试及B证(安全员)多少钱
  16. 关于正当防卫的几个案例分析
  17. 河海大学厕所上吊自杀 为情所困再发2起命案
  18. “你的电脑遇到问题需要重启”如何解决
  19. oracle根据身份证更新出生日期(15位与18位身份证都可)
  20. javascript--防通过ifarme钓鱼

热门文章

  1. java web 课堂笔记第一
  2. 特征交互新路线|阿里 Co-action Network论文解读
  3. 创立了维基百科的人,竟然要颠覆维基百科?| 独家
  4. Unity WEBGL设置浏览器全屏
  5. OpenHarmony3.0如何轻松连接华为云IoT设备接入平台?
  6. 安卓系统培训!系统盘点Android开发者必须掌握的知识点,BAT大厂面试总结
  7. QQ群视频出现imsdk登录失败的解决方法
  8. 怎样对平面中的点进行顺时针或者逆时针排序
  9. 拆解金融科技Q3业绩:增长、迭代与飞轮效应
  10. 模块例化是怎么进行的?——FPGA学习笔记(四)