SpringCloudspring boot

Spring Cloud Eureka 客户端服务快速上下线

2019-05-20  本文已影响139人  sprainkle

问题描述

在开发环境联调接口过程中,出现bug 或 新增属性方法 或其他需要重启服务才能让新代码生效的情况,是再正常不过的事了,如果是单体应用还好,重启就能直接用了,但如果是Spring Cloud微服务应用就不一样了,因为我们调用接口都是会经过网关,然后网关再通过负载均衡将请求转发后可用的服务实例,这一切很大程度上依赖于Service Discovery(服务发现,即Spring Cloud Eureka,当然还有其他服务发现框架,这里主要讨论Eureka),当服务重启后,你会发现有一小段时间重新启动的服务变成不可用。

问题原因

比较了解Eureka的人都知道,Eureka Server 有2个缓存,一个是可读写缓存(readWriteCacheMap),另一个是只读缓存(readCacheMap),这2个缓存存放的都是所有Eureka Client服务的服务实例列表,不过这2个Cache有不同的用途。可以简单地这样理解:

然而,Eureka ClientEureka Server请求获取服务实例列表时,Server端返回的是readCacheMap这个缓存里边的内容,所以就会出现请求的服务没有可用的服务实例。

服务重启后变成不可用,过段时间又变成可用的流程,具体可参考如下时序图:


eureka 服务上下线

解决方案

既然知道问题所在,只要解决思路就清晰了,无非就是缩短readWriteCacheMap缓存更新到readCacheMap中的时间,再一个是缩短Eureka Client服务从Eureka Server获取新的服务实例列表的时间;当然,还需要其他配置的配合,比如主动让不可用服务时效掉,因为Spring Cloud的负载均衡默认实现是Ribbon,所以还需要缩短其刷新负载列表的时间。具体配置如下:

Eureka Server

eureka:
  server:
    # 默认30s. eureka server刷新readCacheMap的时间,注意,client读取的是readCacheMap,
    # 这个时间决定了多久会把readWriteCacheMap的缓存更新到readCacheMap上
    response-cache-update-interval-ms: 3000
    # 默认60s. 启用主动失效,并且每次主动失效检测间隔为5s.
    eviction-interval-timer-in-ms: 5000
  instance:
    # 默认90s. 服务过期时间配置,超过这个时间没有接收到心跳EurekaServer就会将这个实例剔除.
    # 注意,EurekaServer一定要设置eureka.server.eviction-interval-timer-in-ms否则这个配置无效,这个配置一般为服务刷新时间配置的三倍
    lease-expiration-duration-in-seconds: 15
    # 默认30s. 服务刷新时间配置,每隔这个时间会主动心跳一次
    lease-renewal-interval-in-seconds: 5

Eureka Client

eureka:
  client:
    # eureka client刷新本地缓存时间
    registryFetchIntervalSeconds: 5
ribbon:
  # eureka客户端ribbon刷新时间
  ServerListRefreshInterval: 5000

友情提醒

这套配置,比较适合在开发阶段使用,因为我们希望重启的服务能尽快可用。但是线上环境就需要根据具体情况更改配置,当然如果线上环境的服务实例数比较少,也是可以考虑使用上述配置。

推荐阅读

Spring Cloud 进阶玩法

上一篇 下一篇

猜你喜欢

热点阅读