eureka 优雅升级

问题

目前公司使用spring cloud eureka ,eureka server 和 client 有缓存,并且服务列表更新pull方式,在服务发布期间,会出现服务调用失败的情况,主要原因如下

  1. 目前开启是readonlyCache,client端获取的配置是从server端接口获取,server 从readOnlyMap获取返回,readOnlyMap 默认是30s
  2. client 默认会有一个30s 的定时任务,从server获取配置,缓存到本地serverList
  3. 目前服务下线会自动调用eureka server,注销自己,所以现在主要原因是serverList 在client和server有缓存
  4. 如果使用了ribbon做客户端负载和feign调用,ribbon也会有30s的serverList缓存,会有传说中的2min time lag 问题
  5. eureka 目前不在维护,这个问题官方没有提供一个很好的解决方案

版本

spring boot 版本:1.5.13.RELEASE
spring cloud 版本:Edgware.SR3

解决方案1

  1. 针对如下错误信息自动重试
  • connect refuse
  • connect time out
  1. client 和 server 端的缓存 时间缩短到5s 更新一次,这样最大的延迟时间是10s,但是会增加eureka 的qps,增加6倍,为了减少qps,只针对gateway和job 做缓存5s配置,因为其他服务只是调用方,这样只是增加了4台服务器的qps,其他服务不变
  2. 这样基本可以解决调用问题

解决方案2

  1. 针对如下错误信息自动重试
  • connect refuse
  • connect time out
  1. eureka 关闭使用readOnlyCache 所有从readCache中读取,这样所有问题是在client,client缩短缓存更新时间即可。但是还是会有服务不可能的情况,是方案1的一半时间,还是解决不了根本问题

解决方案3(激进型)

  1. 关闭 eureka server 的缓存
  2. client 在注销本机服务,mq 广播
  3. 所有client 监听mq,如果有消息,主动拉取服务器的配置

方案对比

  1. 方案1和方案2对比,其实没有本质区别,只是server没有了缓存,但是读写都从readWriteMap中获取,会有锁竞争的情况,会影响性能,比较倾向方案1
  2. 方案3缺点:
  • 发布期间会有广播风暴,api 实例如果是50台实力,发布期间会有50次广播,eureka server 是49*49次qps,适合服务节点比较少
  • 每台机器都要引入mq依赖,需要重写源码

最终方案

先通过重试+client、server 缓存缩短的方式可以解决99%的问题,剩下方案3也解决不了,如read time out 服务提供方下线。reset by peer 客户端下线服务,主动断开链接,这两种情况都有可能业务已处理完成,不能重试,需要排查

ribbon:
  ServerListRefreshInterval: 4000

eureka:
  client:
    registryFetchIntervalSeconds: 4

eureka:
  server:
    responseCacheUpdateIntervalMs: 5000

相关配置类:

  1. eureka server 配置类:DefaultEurekaServerConfig 使用的是驼峰形式
  2. ribbon配置类:DefaultClientConfigImpl 使用的是驼峰形式,刷新缓存类PollingServerListUpdater
  3. eureka client 配置类:EurekaClientConfigBean 配置也是驼峰形式