公司的项目要做优雅停机,记录下遇到的一些坑,常规的就不写了。
环境:
- JDK1.8
- spring cloud Daltson.RELEASE
- spring boot 1.5.13.RELEASE
1.只集成actuator,开放出shutdown端点是不够的,需要在关闭前处理好线程池中未结束的线程。否则还是暴力停机,线程被直接中断了,业务也无法完成。具体解决方案参考https://github.com/spring-projects/spring-boot/issues/4657
2.步骤1完成后,调用shutdown抛出异常:
org.springframework.beans.factory.BeanCreationNotAllowedException:
Error creating bean with name 'eurekaInstanceConfigBean':
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!)
解决办法:参考https://github.com/spring-cloud/spring-cloud-netflix/issues/2099
3.步骤2完成后,调用shutdown抛出异常:
org.springframework.beans.factory.BeanCreationNotAllowedException:
Error creating bean with name 'registrationListener': 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!)
解决办法:经过排查,是引入了sprin-boot-admin-starter-client
包,发生了冲突,去掉这个jar包的引用即可正常。或者不能去掉的情况下,修改一下步骤2中的代码,即可解决异常。
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (containsBeanDefinition(beanFactory, "feignContext", "eurekaAutoServiceRegistration")) {
BeanDefinition bd = beanFactory.getBeanDefinition("feignContext");
bd.setDependsOn("eurekaAutoServiceRegistration","registrationListener");
}
}
private boolean containsBeanDefinition(ConfigurableListableBeanFactory beanFactory, String... beans) {
return Arrays.stream(beans).allMatch(b -> beanFactory.containsBeanDefinition(b));
}