当前位置:   article > 正文

Eureka下线延迟

Eureka下线延迟

Eureka下线延迟

导言
Spring-Cloud使用Eureka作为服务注册与发现时,网关与服务共同将服务实例注册到注册中心,然后由注册中心将所有的实例信息同步给每个服务实例,网关就是通过与注册中心同步的服务实例来进行路由选择(通常采用ribbon来做负载均衡策略)。

问题1
假设注册中心为R,网关为Z,服务有A/B/C三个,此时若准备重新部署A服务,则A先从R掉线(DOWN),然后R同步实例信息给Z,部署期间客户端请求发到Z后原则上应该被路由到B/C,但由于实例信息同步机制的时效性原因导致实际上被路由到A/B/C,导致部分路由到A的请求出现异常响应。

问题2
调用/actuator/shutdown优雅停机,遇到问题1中异常响应持续的时间持续大概1s左右,通过断点观察ShutdownEndpoint类的执行过程发现在执行到AbstractApplicationContext的doClose方法(990行)时调用destroyBeans()销毁Beans大概耗费了1s左右。于是,追踪DefaultListableBeanFactory类的destroySingletons()方法(727行)找到以下销毁Beans的代码:

// 这里可以看到spring容器管理的Beans,以目前我的项目为例总计49个,销毁时大约消耗1100ms.
for(int i = disposableBeanNames.length - 1; i >= 0; --i) {
    this.destroySingleton(disposableBeanNames[i]);
}
  • 1
  • 2
  • 3
  • 4

至此,报错原因找到,销毁Bean的期间请求被网关转发到服务,服务并未中止所以请求仍然能被接收,但是部分Spring管理的Bean已被销毁因此接口报出异常BeanCreationNotAllowedException

思考
虽然主动从注册中心下线的服务,但是网关zuul项目与注册中心的实例同步也需要时间,总会有延迟的情况,至于为什么影响的时间是1s左右还有待观察;
如果能在注册中心下线服务的时候去网关项目剔除到缓存的实例或者刷新缓存,这样在调用shutdown时保证请求不会被网关分配过来应该能解决问题。
有同事给了解决办法是阿里出品的Nacos,这个还有待研究…
你有什么好的建议吗?一起交流,我接下来几天将继续追踪这个问题。

资料
https://www.jianshu.com/p/6ac4810f6f42?tdsourcetag=s_pctim_aiomsg eureka缓存配置
https://www.cnblogs.com/yixinjishu/p/10871243.html eureka缓存机制
https://blog.csdn.net/Mr_Errol/article/details/84938993 服务发现现状分析
https://nacos.io/zh-cn/docs/what-is-nacos.html Nacos文档

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/963329
推荐阅读
相关标签
  

闽ICP备14008679号