Spring cloud学习笔记---Eureka常见配置

时间:2019-01-23
本文章向大家介绍Spring cloud学习笔记---Eureka常见配置,主要包括Spring cloud学习笔记---Eureka常见配置使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

部分转自:http://www.itmuch.com/spring-cloud-sum-eureka/

一、Spring Cloud中,Eureka常见配置与问题总结。

指定Eureka的Environment

eureka.environment: 指定环境

 

指定Eureka的DataCenter

参考文档:https://github.com/Netflix/eureka/wiki/Configuring-Eureka

eureka.datacenter: 指定数据中心

 

解决Eureka注册服务慢的问题

参考文档:https://github.com/Netflix/eureka/wiki/Configuring-Eureka
文中指出,配置-Deureka.datacenter=cloud,这样eureka将会知道是在AWS云上。

使用配置项:

eureka.instance.leaseRenewalIntervalInSeconds

参考文档:
http://cloud.spring.io/spring-cloud-static/Camden.SR1/#_why_is_it_so_slow_to_register_a_service
原文:

Why is it so Slow to Register a Service?
Being an instance also involves a periodic heartbeat to the registry (via the client’s serviceUrl) with default duration 30 seconds. A service is not available for discovery by clients until the instance, the server and the client all have the same metadata in their local cache (so it could take 3 heartbeats). You can change the period using eureka.instance.leaseRenewalIntervalInSeconds and this will speed up the process of getting clients connected to other services. In production it’s probably better to stick with the default because there are some computations internally in the server that make assumptions about the lease renewal period.

翻译:

作为实例还涉及到与注册中心的周期性心跳,默认持续时间为30秒(通过serviceUrl)。在实例、服务器、客户端都在本地缓存中具有相同的元数据之前,服务不可用于客户端发现(所以可能需要3次心跳)。你可以使用eureka.instance.leaseRenewalIntervalInSeconds 配置,这将加快客户端连接到其他服务的过程。在生产中,最好坚持使用默认值,因为在服务器内部有一些计算,他们对续约做出假设。

 

Eureka的自我保护模式

如果在Eureka Server的首页看到以下这段提示,则说明Eureka已经进入了保护模式。

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.

保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。

详见:https://github.com/Netflix/eureka/wiki/Understanding-Eureka-Peer-to-Peer-Communication

 

Eureka Server不踢出已关停的节点的问题

在开发过程中,我们常常希望Eureka Server能够迅速有效地踢出已关停的节点,但是新手由于Eureka自我保护模式,以及心跳周期长的原因,常常会遇到Eureka Server不踢出已关停的节点的问题。解决方法如下:

(1) Eureka Server端:配置关闭自我保护,并按需配置Eureka Server清理无效节点的时间间隔。

eureka.server.enable-self-preservation # 设为false,关闭自我保护
eureka.server.eviction-interval-timer-in-ms # 清理间隔(单位毫秒,默认是60*1000)

(2) Eureka Client端:配置开启健康检查,并按需配置续约更新时间和到期时间。

eureka.client.healthcheck.enabled # 开启健康检查(需要spring-boot-starter-actuator依赖)

eureka.instance.lease-renewal-interval-in-seconds # 续约更新时间间隔(默认30秒)

eureka.instance.lease-expiration-duration-in-seconds # 续约到期时间(默认90秒)

示例:
服务器端配置:

eureka:
    server:
        enable-self-preservation: false
        eviction-interval-timer-in-ms: 4000

客户端配置:

eureka:
    client:
        healthcheck:
            enabled: true
    instance:
        lease-expiration-duration-in-seconds: 30
        lease-renewal-interval-in-seconds: 10

注意:
更改Eureka更新频率将打破服务器的自我保护功能,生产环境下不建议自定义这些配置。
详见:https://github.com/spring-cloud/spring-cloud-netflix/issues/373

注意点:eureka.client.healthcheck.enabled=true配置项必须设置在application.yml中

eureka.client.healthcheck.enabled=true 只应该在application.yml中设置。如果设置在bootstrap.yml中将会导致一些不良的副作用,例如在Eureka中注册的应用名称是UNKNOWN等。

 

自定义Eureka的Instance ID

在Spring Cloud中,服务的Instance ID的默认值是${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} ,也就是机器主机名:应用名称:应用端口 。因此在Eureka Server首页中看到的服务的信息类似如下:itmuch:microservice-provider-user:8000 。如果想要自定义这部分的信息怎么办?

访问实例时url指向 → 主机名+端口号 ,这样是访问不到的,只能通过 主机IP+端口号才能访问

示例:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ipAddress}:${server.port} # 将Instance ID设置成IP:端口的形式
    hostname= ${spring.cloud.client.ipAddress} #设置主机名为主机ip

Eureka配置最佳实践
参考https://github.com/spring-cloud/spring-cloud-netflix/issues/203

Eureka的自我注册问题

在默认设置下,Eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为。 
禁止方式如下

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

如果不禁止的话,会得到如下错误:

com.netflix.discovery.DiscoveryClient    : DiscoveryClient_UNKNOWN/DESKTOP-MQ8D0C9:8761 - was unable to refresh its cache! status = Cannot execute request on any known server

因为当注册中心将自己作为客户端注册的时候,发现在server上的端口被自己占据了,然后就挂了。如果要开启自动注册的话,可以启动两个server,两两互相注册,例如:

A:eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 
B:eureka.client.serviceUrl.defaultZone=http://localhost:8762/eureka/

Eureka server和client之间每隔30秒会进行一次心跳通信,告诉server,client还活着。由此引出两个名词:

 Renews threshold:server期望在每分钟中收到的心跳次数 
 Renews (last min):上一分钟内收到的心跳次数。

Eurake有一个配置参数eureka.server.renewalPercentThreshold,定义了renews 和renews threshold的比值,默认值为0.85。当server在15分钟内,比值低于percent,即少了15%的微服务心跳,server会进入自我保护状态,Self-Preservation。在此状态下,server不会删除注册信息,这就有可能导致在调用微服务时,实际上服务并不存在。 
这种保护状态实际上是考虑了client和server之间的心跳是因为网络问题,而非服务本身问题,不能简单的删除注册信息

stackoverflow上,有人给出的建议是: 

1、在生产上可以开自注册,部署两个server 
2、在本机器上测试的时候,可以把比值调低,比如0.49 
3、或者简单粗暴把自我保护模式关闭