重新定义Spring Cloud实战
上QQ阅读APP看书,第一时间看更新

3.4 Eureka参数调优及监控

若要深入了解一个开源组件,从解读其参数入手,不失为一种好的研读代码的方法,本节首先讲解Eureka的核心参数,然后讲解参数的调优及监控。

3.4.1 核心参数

下面主要分为Client端及Server端两大类来简述一下Eureka的几个核心参数。

1. Client端

这里笔者将Client端的参数分为基本参数、定时任务参数、http参数三大类来梳理。

1)基本参数如表3-5所示。

表3-5 Eureka Client参数说明

2)定时任务参数如表3-6所示。

表3-6 Eureka Client定时任务参数

3)http参数。Eureka Client底层httpClient与Eureka Server通信,提供的相关参数如表3-7所示。

表3-7 Eureka Client http相关参数

2. Server端

笔者将Server端的参数分为如下几类:基本参数、response cache参数、peer相关参数、http参数。

(1)基本参数

基本参数列表如表3-8所示。

表3-8 eureka server基本参数

(2)response cache参数

Eureka Server为了提升自身REST API接口的性能,提供了两个缓存:一个是基于ConcurrentMap的readOnlyCacheMap,一个是基于Guava Cache的readWriteCacheMap。其相关参数如表3-9所示。

表3-9 Eureka Server response cache参数

(3)peer相关参数

peer相关系数的说明如表3-10所示。

表3-10 Eureka Server peer相关参数

(4)http参数

Eureka Server需要与其他peer节点进行通信,复制实例信息,其底层使用httpClient,提供的相关参数如表3-11所示。

表3-11 Eureka Server http相关参数

3.4.2 参数调优

1.常见问题

对于新接触Eureka的开发人员来说,一般会有几个困惑:

❑ 为什么服务下线了,Eureka Server接口返回的信息还会存在。

❑ 为什么服务上线了,Eureka Client不能及时获取到。

❑ 为什么有时候会出现如下提示:

        EMERGENCY!  EUREKA  MAY  BE  INCORRECTLY  CLAIMING  INSTANCES  ARE  UP  WHEN  THEY'RE
            NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT
            BEING EXPIRED JUST TO BE SAFE

2.解决方法

对于第一个问题,Eureka Server并不是强一致的,因此registry中会存留过期的实例信息,这里头有几个原因:

❑ 应用实例异常挂掉,没能在挂掉之前告知Eureka Server要下线掉该服务实例信息。这个就需要依赖Eureka Server的EvictionTask去剔除。

❑ 应用实例下线时有告知Eureka Server下线,但是由于Eureka Server的REST API有response cache,因此需要等待缓存过期才能更新。

❑ Eureka Server由于开启并引入了SELF PRESERVATION模式,导致registry的信息不会因为过期而被剔除掉,直到退出SELF PRESERVATION模式。

针对Client下线没有通知Eureka Server的问题,可以调整EvictionTask的调度频率,比如下面配置将调度间隔从默认的60秒,调整为5秒:

        eureka.server.eviction-interval-timer-in-ms=5000

针对response cache的问题,可以根据情况考虑关闭readOnlyCacheMap:

        eureka.server.use-read-only-response-cache=false

或者调整readWriteCacheMap的过期时间:

        eureka.server.response-cache-auto-expiration-in-seconds=60

针对SELF PRESERVATION的问题,在测试环境可以将enable-self-preservation设置为false:

        eureka.server.enable-self-preservation=false

关闭的话,则会提示:

        THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY
          IN CASE OF NETWORK/OTHER PROBLEMS.

或者:

        RENEWALS ARE LESSER THAN THE THRESHOLD. THE SELF PRESERVATION MODE IS TURNED
            OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.

针对新服务上线,Eureka Client获取不及时的问题,在测试环境,可以适当提高Client端拉取Server注册信息的频率,例如下面将默认的30秒改为5秒:

        eureka.client.registry-fetch-interval-seconds=5

针对SELF PRESERVATION问题,下面我们来重点讨论一下。

在实际生产过程中,经常会有网络抖动等问题造成服务实例与Eureka Server的心跳未能如期保持,但是服务实例本身是健康的,这个时候如果按照租约剔除机制剔除的话,会造成误判,如果大范围误判的话,可能会导致整个服务注册列表的大部分注册信息被删除,从而没有可用服务。Eureka为了解决这个问题引入了SELF PRESERVATION机制,当最近一分钟接收到的续约的次数小于等于指定阈值的话,则关闭租约失效剔除,禁止定时任务剔除失效的实例,从而保护注册信息。对于开发测试环境,开启这个机制有时候反而会影响系统的持续集成,因此可以通过如下参数关闭该机制:

        eureka.server.enableSelfPreservation=false

在生产环境中,可以把renewalPercentThreshold及leaseRenewalIntervalInSeconds参数调小一点,进而提高触发SELF PRESERVATION机制的门槛,比如:

        eureka.instance.leaseRenewalIntervalInSeconds=10  ##默认30
        eureka.server.renewalPercentThreshold=0.49       ##默认0.85

3.4.3 指标监控

Eureka内置了基于servo的指标统计,具体详见com/netflix/eureka/util/EurekaMonitors. java类,其统计指标如表3-12所示。

表3-12 Eureka监控指标

Spring Boot 2.x版本改为使用Micrometer,不再支持Netflix Servo,转而支持了Netflix Servo的替代者Netflix Spectator。不过对于Servo,可以通过DefaultMonitorRegistry.getInstance(). getRegisteredMonitors()来获取所有注册了的Monitor,进而获取其指标值。