背景
某个周六的中午,领导突然找我说线上有大量报错,让我看一下。我发现日志中出现了很多下面的报错信息,而且持续了一段时间(后面才发现收到了告警邮件,但是当时手机没有提醒,强行甩锅…):
org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'xxxController': 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!)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:208)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.web.method.HandlerMethod.createWithResolvedBean(HandlerMethod.java:323)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:367)
排查过程
- 查找是否有慢查询:当时找到了一个慢查询sql,但是分析后,应该不是影响本次报错的根本原因
- 查找是否有其它报错日志:本服务基本上都是这个报错,其它调用方服务因为本服务的影响,出现了请求500的报错
- 切换读源:由于此块业务是核心业务且还是
双写+读阶段
,故赶紧将读请求转移到原始项目 - 观看 Grafana 监控:后来其中一个同事说
docker的cpu使用率
和docker的内存使用率
在某个时间节点开始发生了持续的断层(容器自动重启),仔细一看,在断层开始前,系统流量出现了一个小高潮。然后赶紧找运维同事帮忙检查下容器自身的配置。果不其然,本服务的几个实例配置的JVM堆内存不够用了,增大配置后,调用请求恢复了正常。
报错分析
系统出现峰值的时候,确实流量上去了一些,但是伴随出现了一
- BeanFactory工厂正在销毁
- 此时调用刚好执行到去工厂中获取bean(bean是单例)
- 造成上文中的报错
后续
- 增量修
七墨博客 复数据(通过增量迁移Job很快修复完成) - 切换读源:将读请求切到本服务
- 针对上文提到的慢查询,优化代码查询逻辑
- 运维层面:运维同事说后期会动态监控系统调用量,保证动态分配实例资源