Eureka是Netflix公司开源的一款基于REST的服务自动注册和发现的产品,如下图所示Eureka可以分为三个部分:
Eureka-Server:提供服务注册和发现。
Eureka-Client-Service-Provider:服务提供者,通过Rest告知服务端注册,更新,取消服务。
Eureka-Client-Service-Consumer:服务消费者,通过Rest从服务端获取需要服务的地址列表,然后配合一些负载均衡策略来调用相关的服务。
Eureka Server中会保存一份所有Service注册信息的map,将InstanceInfo中的元数据信息存储在一个 ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>
对象中,它是一个双层Map结构,第一层的存储 服务名-appName
,第二层的存储 实例名-instanceId
属性。
如果没有设置 eureka.instance.appName
默认使用 spring.application.name
,如果没有设置 eureka.instance.instanceId
则默认是 CLIENT IP:PORT
。
Eureka Client每隔一段时间都会向Eureka Server发送一个心跳声明自己目前处于正常的状态。
Eureka会定期检查是否有服务已经失效,检测的标准就是超过指定的时间没有进行续约的服务,这个指定的时间可以通过 eureka.instance.lease-expiration-duration-in-seconds=90
来指定,Eureka Server定期检查的时间可以通过 eureka.instance.lease-renewal-interval-in-seconds=30
来设置。
当一个Eureka Client向一个Eureka Server实例注册/续约/剔除之后,这台Eureka Server需要将相关的信息同步更新到其他的Eureka Server。
Service Provider(Eureka Client)主要负责下面几个任务:
Service Provider要对外提供服务,一个很重要的步骤就是向Eureka Server去注册。
Service Provider每个一定时间就会通知Eureka Server来表明自己依然还活着,这个参数默认是30s,可以通过 eureka.instance.leaseRenewalIntervalInSecends
来设置。
在Service Provider要Shutdown的时候,需要及时通知Eureka Server将自己剔除,避免Consumer调用不存在的服务,这可以通过调用 DiscoveryManager.getInstance().shutdownComponent()
来实现。
通过 eureka.client.fetch-registry=true
来允许从Eureka Server获取服务列表。
Consumer会在本地保存一份所有服务的缓存列表,每隔一定的时间都会重新向Eureka Server查询来更新这份列表,这个参数可以通过 eureka.client.registry-fetch-interval-seconds=30
来指定这个时间。p.s: Consumer也是属于Eureka Client。
当Erueka Client向Eureka Server注册一个服务,有时候我们会发现不能从Consumer立即读取到注册服务,主要有下面四个原因: