Eureka常见问题
Eureka注册服务慢
- 默认情况,服务注册到Eureka Server 的过程比较慢。在开发或者测试时候,如果能够加速注册的过程,从而提升工作效率。
- Spring Cloud官方文档详细描述了该问题的原因并提供了解决方案:
//原文
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.
- 解释如下:服务的注册涉及到周期性的心跳检测,默认Eureka是30秒发送异常心跳(通过客户端配置的serviceUrl)。只有当前实例,服务器端和客户端的本地缓存中的元数据都相同的时候,服务才能被其他客户端发现(所以可能需要3次心跳)。可以使用参数eureka.instance.leaseRenewalIntervalInSeconds修改时间间隔,从而加快客户端连接到其他服务的过程。在生成环境中最好使用默认的值,因为在服务器内部有一些计算,这些配置的修改都会对其进行影响。
Eureka已停的微服务节点注销慢或不注销
- 在开发环境,我们希望Eureka Server能迅速有效的注销已经停止的微服务实例。然而,由于Eureka Server 清理无效节点的周期比较长(默认90s),以及自我保护模式等原因,可能会遇到微服务注销慢甚至不注销的情况。解决方案如下:
- Eureka Server端:配置关闭自我保护,并且按需配置Eureka Server清理无效节点的时间间隔。配置如下:
eureka.server.enable-self-preservation
#设置为false,关闭自我保护,从而保证会注销微服务
eureka.server.eviction-interval-tomer-in-us
#清理间隔(单位毫秒,默认60*1000)
- Eureka Client端:配置开启健康检查,并按照业务需要配置续约更新时间和到期时间。配置如下:
eureka.client.healthcheck.enabled
#设为true,开启健康检查(需要添加依赖spring-boot-starter-actuator)
eureka.instance.lease-renewal-interval-in-seconds
#续约更新时间间隔,默认30秒
eureka.instance.lease-expiration-duration-in-seconds
#续约到期时间默认90秒
- 以上的配置仅建议在开发的时候,测试的时候用,生产环境如非必要建议坚持使用默认值,因为修改Eureka的续约评率可能会打破Eureka的自我保护特性,这就意味着生产环境中如果真正遇到网络问题或者其他情况无法注册,或者无法发送心跳等情况,此时Eureka的自我保护也无法使用,可能导致更严重的问题,所以坚持默认配置还是有好处的,具体情况结合实际业务需求来改变。如下配置示例
#Server配置示例server:enable-self-preservation: falseeviction-interval-timer-in-ms: 4000
#client配置示例
server:port: 8761
eureka:client:registerWithEureka: falsefetchRegistry: falseserviceUrl:defaultZone: http://localhost:8761/eurekahealthcheck:enable: trueinstance:lease-expiration-duration-in-seconds: 30lease-renewal-interval-in-seconds: 10
- 以下界面表示处于自我保护状态下的Eureka界面截图信息:
自定义微服务的InstandeID
- InstanceID用于唯一事变注册到Eureka Server上的微服务实例。在Eureka的首页可以直观的看到各个微服务的InstanceID,如上图中所示,localhost:microservice-consumer-business:8080就是instanceID
- Spring Cloud中,服务的InstanceID默认值是${spring.cloud.client.hostname}: ${spring.aplication.name}: &{spring.aplication.instance_id: ${server.port}}。如果想自定义这部分内容,只需要在微服务中配置eureka.instance.instance-id,如下案例:
server:port: 8001
spring:application:name: microservice-provider-user
eureka:instance:prefer-ip-address: trueinstance-id: ${spring.cloud.client.ipAddress}:${server.port}
- 这样配置后,可以将微服务microservice-provider-user的instanceID设置为ip:端口的形式。效果如下
Eirela的UNKNOWN问题总结与解决
- 注册信息UNKNOWN,在刚开始学SpringCloud的时候遇到过这个问题,如下图,有两种UNKNOWN的情况,一种是应用名称UNKNOW,另外一种是应用状态的UNKNOWN,下面分别讨论两种情况
应用名称UNKNOWN
- 应用名称UNKNOWN显然是不应该存在于任何环境下的微服务机器中,首先是微服务的名字不能够望文见意,无法直观看出这个那个服务;更重要的是,我们经常使用引用名称消费对应的微服务的接口,比如我们用FegnClient的时候,必须用到服务名称。
- 一般来说,有两种情况可能导致这个问题的产生:
- 未配置spring.application.name或者eureka.instance.appname属性(配置了但是名称没有写配置的是空值)。如果这两个属性均是空,就会导致应用名称UNKNIWN的问题。
- 某些版本的SpringFox会导致这个问题,不让SpringFox2.6.0。建议使用SpringFox2.6.1或者更高的版本。
微服务状态UNKNOWN
- 微服务状态UNKNOWN同样麻烦,一般情况,Loadbalance负责均衡器只会请求UP状态的服务器。该问题一般由监考检查导致的
- eureka.client.healthcheck.enabled=true必须设置在application.yml中,而不能设置在bootstrap.yml中,否则一下场景下会导致应用状态UNKNOWN的问题。
Hystrix/Feign 整合Hystrix后首次请求失败
- 在某些场景下,Feign或者Ribbon整合Hystrix后,会出现首次调用失败的问题。
原因分析
- Hystrix默认的超时时间是1秒,如果在1秒内得不到响应,就会进入fallback逻辑。由于Spring的懒加载机制,首次请求会比较慢,因此在某些机器(例如配置比较低的机器)上,上次请求需要的时间可能会大于1秒。因此出现这个问题
解决方案
- 方法一,延长Hystrix的超时时间,如下配置可以让Hystrix超时时间修改为5秒:
hystrix.command.default.execution.timeout.enabled: false
- 方法二:禁用Hystrix的超时,配置示例如下:
Hystrix.command.default.execution.timeout.enabled:false
- 方法三:对于Feign,还将可以禁用Hystrix,这样既可以为Feign全局禁用Hystrix支持,不过这种方式比较极端,不推荐这样做。示例如下:
feign.hystrix.enabled: false
[下一篇 SpringCloud常见问题总结(二)(https://blog.csdn.net/liaojiamin0102/article/details/107408563)