一次服务更新进行升级时
October 18th 2018, 18:05:35.767 [545]: ++ exit 143
October 18th 2018, 18:05:35.610 [545]: 2018-10-18 18:05:35.611 INFO 13 --- [ Thread-10] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
October 18th 2018, 18:05:35.608 [545]:
October 18th 2018, 18:05:35.608 [545]: at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1009)
October 18th 2018, 18:05:35.608 [545]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523)
October 18th 2018, 18:05:35.608 [545]: at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1033)
October 18th 2018, 18:05:35.608 [545]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961)
October 18th 2018, 18:05:35.608 [545]: at org.springframework.context.support.AbstractApplicationContext$2.run(AbstractApplicationContext.java:928)
October 18th 2018, 18:05:35.608 [545]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968)
October 18th 2018, 18:05:35.607 [545]: at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:389)
October 18th 2018, 18:05:35.607 [545]: at org.springframework.cloud.context.named.NamedContextFactory.destroy(NamedContextFactory.java:76)
October 18th 2018, 18:05:35.607 [545]: at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:994)
October 18th 2018, 18:05:35.607 [545]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578)
October 18th 2018, 18:05:35.607 [545]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554)
October 18th 2018, 18:05:35.607 [545]: at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:961)
October 18th 2018, 18:05:35.607 [545]: at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:272)
October 18th 2018, 18:05:35.607 [545]: at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337)
October 18th 2018, 18:05:35.606 [545]: at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
October 18th 2018, 18:05:35.606 [545]: at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:250)
October 18th 2018, 18:05:35.606 [545]: at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:137)
October 18th 2018, 18:05:35.606 [545]: at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
October 18th 2018, 18:05:35.606 [545]: at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:174)
October 18th 2018, 18:05:35.606 [545]: at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
October 18th 2018, 18:05:35.606 [545]: at org.springframework.context.event.ApplicationListenerMethodAdapter.getTargetBean(ApplicationListenerMethodAdapter.java:280)
October 18th 2018, 18:05:35.605 [545]:
October 18th 2018, 18:05:35.605 [545]: org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'eurekaAutoServiceRegistration': 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!)
October 18th 2018, 18:05:35.605 [545]: at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
October 18th 2018, 18:05:35.605 [545]: at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
October 18th 2018, 18:05:35.605 [545]: 2018-10-18 18:05:35.604 WARN 13 --- [ Thread-10] s.c.a.AnnotationConfigApplicationContext : Exception thrown from ApplicationListener handling ContextClosedEvent
October 18th 2018, 18:05:35.605 [545]: at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
October 18th 2018, 18:05:35.605 [545]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:216)
October 18th 2018, 18:05:35.601 [545]: at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1009)
October 18th 2018, 18:05:35.601 [545]: at org.springframework.context.support.AbstractApplicationContext$2.run(AbstractApplicationContext.java:928)
October 18th 2018, 18:05:35.601 [545]:
October 18th 2018, 18:05:35.601 [545]: 2018-10-18 18:05:35.603 INFO 13 --- [ Thread-10] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@145bce9d: startup date [Thu Oct 18 12:35:30 GMT+08:00 2018]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@50e8e914
October 18th 2018, 18:05:35.601 [545]: at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1033)
October 18th 2018, 18:05:35.600 [545]: at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:272)
October 18th 2018, 18:05:35.600 [545]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961)
October 18th 2018, 18:05:35.600 [545]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968)
October 18th 2018, 18:05:35.600 [545]: at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:961)
October 18th 2018, 18:05:35.600 [545]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578)
October 18th 2018, 18:05:35.600 [545]: at org.springframework.cloud.context.named.NamedContextFactory.destroy(NamedContextFactory.java:76)
October 18th 2018, 18:05:35.600 [545]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554)
October 18th 2018, 18:05:35.600 [545]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523)
October 18th 2018, 18:05:35.599 [545]: at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:137)
October 18th 2018, 18:05:35.599 [545]: at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
October 18th 2018, 18:05:35.599 [545]: at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
October 18th 2018, 18:05:35.599 [545]: at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337)
October 18th 2018, 18:05:35.599 [545]: at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:994)
October 18th 2018, 18:05:35.599 [545]: at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
October 18th 2018, 18:05:35.599 [545]: at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:389)
October 18th 2018, 18:05:35.598 [545]: at org.springframework.context.event.ApplicationListenerMethodAdapter.getTargetBean(ApplicationListenerMethodAdapter.java:280)
October 18th 2018, 18:05:35.598 [545]: at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
October 18th 2018, 18:05:35.598 [545]: at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
October 18th 2018, 18:05:35.598 [545]: at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:250)
October 18th 2018, 18:05:35.598 [545]: at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
October 18th 2018, 18:05:35.598 [545]: at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:174)
October 18th 2018, 18:05:35.597 [545]: 2018-10-18 18:05:35.598 WARN 13 --- [ Thread-10] s.c.a.AnnotationConfigApplicationContext : Exception thrown from ApplicationListener handling ContextClosedEvent
October 18th 2018, 18:05:35.597 [545]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:216)
October 18th 2018, 18:05:35.597 [545]: org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'eurekaAutoServiceRegistration': 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!)
October 18th 2018, 18:05:35.597 [545]:
October 18th 2018, 18:05:35.596 [545]: 2018-10-18 18:05:35.597 INFO 13 --- [ Thread-10] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1ec4d67e: startup date [Thu Oct 18 15:17:15 GMT+08:00 2018]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@50e8e914
The root cause is when closing ApplicationContext, it will destroy all singleton bean, eurekaAutoServiceRegistration is destroyed first, then feignContext. When destroy feignContext, it will close the ApplicationContext associated with each FeignClient. Since eurekaAutoServiceRegistration listen on ContextClosedEvent, those events will be sent to that bean. Unfortunately because it has been destroyed, so we got the above exception (try to create bean in destruction).
@EventListener(ContextClosedEvent.class)
public void onApplicationEvent(ContextClosedEvent event) {
// register in case meta data changed
stop();
}
根本原因是:当关闭ApplicationContext,会关闭所有的单例:先是eurekaAutoServiceRegistration,然后是feignContext。当关闭feignContext时,会关闭与每个FeignClient关联的ApplicationContext,因为eurekaAutoServiceRegistration监听ContextClosedEvent,ContextClosedEvent的所有事件将会被发送到那个bean上,因为它已经被关闭了,所以会出现上面异常。
Found a workaround. Also added more details about the root cause.
When ApplicationContext shutdown, it will destroy all disposable beans (and beans depend on them). In this case:
FeignContext implements DisposableBean interface
InetUtils implements AutoCloseable interface
EurekaServiceRegistry has a public close method
So they are all considered as disposable beans. Since EurekaAutoServiceRegistration depends on InetUtils and EurekaServiceRegistry beans, so if either bean is destroyed, EurekaAutoServiceRegistration will be destroyed.
Destroy follow First In, Last Out order. Usually application code will not depends on InetUtils or EurekaServiceRegistry, but they depends on FeignClient interfaces. That means FeignContext usually get instituted before InetUtils and EurekaServiceRegistry, so it will be destroyed after them:
InetUtils or EurekaServiceRegistry to be destroyed.
Destroy EurekaAutoServiceRegistration first.
Destroy InetUtils and EurekaServiceRegistry.
Destroy FeignContext which will shutdown all ApplicationContext associated with FeignClients.
EurekaAutoServiceRegistration listen on ContextClosedEvent but it has been destroyed. ApplicationContext will try to create it again, got exception.
Workaround
Make sure InetUtils and EurekaServiceRegistry are instituted before FeignContext. So the sequence become:
Destroy FeignContext which will shutdown all ApplicationContext associated with FeignClients.
EurekaAutoServiceRegistration listen on ContextClosedEvent and processed those events.
InetUtils or EurekaServiceRegistry to be destroyed.
Destroy EurekaAutoServiceRegistration first.
Destroy InetUtils and EurekaServiceRegistry.
There are several ways to do that. The recommended solution is implement a BeanFactoryPostProcessor:
一个 解决方案:
@Component
public class FeignBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (containsBeanDefinition(beanFactory, "feignContext", "eurekaAutoServiceRegistration")) {
BeanDefinition bd = beanFactory.getBeanDefinition("feignContext");
bd.setDependsOn("eurekaAutoServiceRegistration");
}
}
private boolean containsBeanDefinition(ConfigurableListableBeanFactory beanFactory, String... beans) {
return Arrays.stream(beans).allMatch(b -> beanFactory.containsBeanDefinition(b));
}
}
这个问题还有更好的解决方案 上述的解决方案 貌似只是让异常不再抛出来
有其他解决方案 可以留言评论
QQ: 986359351