阅读完需:约 12 分钟
Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service Registry和Service Discovery实现。也是springcloud体系中最重要最核心的组件之一。
中文文档:
https://www.springcloud.cc/spring-cloud-dalston.html#_service_discovery_eureka_clients
服务中心
服务中心又称注册中心,管理各种服务功能包括服务的注册、发现、熔断、负载、降级等,比如dubbo admin后台的各种功能。
有了服务中心调用关系会有什么变化,画几个简图来帮忙理解
项目A调用项目B
正常调用项目A请求项目B

有了服务中心之后,任何一个服务都不能直接去掉用,都需要通过服务中心来调用

项目A调用项目B,项目B在调用项目C

这时候调用的步骤就会为两步:第一步,项目A首先从服务中心请求项目B服务器,然后项目B在从服务中心请求项目C服务。

上面的项目只是两三个相互之间的简单调用,但是如果项目超过20个30个呢?
通过服务中心来获取服务你不需要关注你调用的项目IP地址,由几台服务器组成,每次直接去服务中心获取可以使用的服务去调用既可。
由于各种服务都注册到了服务中心,就有了去做很多高级功能条件。比如几台服务提供相同服务来做均衡负载;监控服务器调用成功率来做熔断,移除服务列表中的故障点;监控服务调用时间来对不同的服务器设置不同的权重等等。
Eureka
按照官方介绍:
Eureka is a REST (Representational State Transfer) based service that is primarily used in the AWS cloud for locating services for the purpose of load balancing and failover of middle-tier servers.
Eureka 是一个基于 REST 的服务,主要在 AWS 云中使用, 定位服务来进行中间层服务器的负载均衡和故障转移。
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server,并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。Spring Cloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。
Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。
用一张图来认识以下:

上图简要描述了Eureka的基本架构,由3个角色组成:
1、Eureka Server
- 提供服务注册和发现
2、Service Provider
- 服务提供方
- 将自身服务注册到Eureka,从而使服务消费方能够找到
3、Service Consumer
- 服务消费方
- 从Eureka获取注册服务列表,从而能够消费服务
Eureka 搭建
Eureka Server
spring cloud已经帮我实现了服务注册中心,我们只需要很简单的几个步骤就可以完成。
1、pom中添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2、添加启动代码中添加@EnableEurekaServer
注解
@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaApplication.class, args);
}
}
3、配置文件
在默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为,在application.yml
添加以下配置:
#给当前的服务取一个名字
spring:
application:
name: eureka
# profiles:
# active: a
#设置端口号
server:
port: 1111
#默认情况下,Eureka也是一个普通的微服务,所以当它还是一个注册中心的时候,它会有两层的身份:1.注册中心,2.普通服务
#即当前服务会自己把自己注册到上面来
eureka:
client:
register-with-eureka: false
fetch-registry: false #表示是否从Eureka Server 上获取信息
-
eureka.client.register-with-eureka
:表示是否将自己注册到Eureka Server,默认为true。 -
eureka.client.fetch-registry
:表示是否从Eureka Server获取注册信息,默认为true。 -
eureka.client.serviceUrl.defaultZone
:设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址。默认是http://localhost:8761/eureka ;多个地址可使用 , 分隔。
配置完成后,就可以启动项目了。
启动工程后,访问:http://localhost:1111/,可以看到下面的页面,其中还没有发现任何服务

Eureka 集群
注册中心这么关键的服务,如果是单点话,遇到故障就是毁灭性的。在一个分布式系统中,服务注册中心是最重要的基础部分,理应随时处于可以提供服务的状态。为了维持其可用性,使用集群是很好的解决方案。Eureka通过互相注册的方式来实现高可用的部署,所以我们只需要将Eureke Server配置其他可用的serviceUrl就能实现高可用部署。
双节点注册中心
首次我们尝试一下双节点的注册中心的搭建。
1.创建两个 application.yml
分布为 application-a.yml 与 application-b.yml

#给当前的服务取一个名字
spring:
application:
name: eureka
#设置端口号
server:
port: 1111
#默认情况下,Eureka也是一个普通的微服务,所以当它还是一个注册中心的时候,它会有两层的身份:1.注册中心,2.普通服务
#即当前服务会自己把自己注册到上面来
eureka:
client:
register-with-eureka: true
fetch-registry: true #表示是否从Eureka Server 上获取信息
service-url:
defaultZone: http://eurekaB:1112/eureka
instance:
hostname: eurekaA #取一个别名
#给当前的服务取一个名字
spring:
application:
name: eureka
#设置端口号
server:
port: 1112
#默认情况下,Eureka也是一个普通的微服务,所以当它还是一个注册中心的时候,它会有两层的身份:1.注册中心,2.普通服务
#即当前服务会自己把自己注册到上面来
eureka:
client:
register-with-eureka: true
fetch-registry: true #表示是否从Eureka Server 上获取信息
service-url:
defaultZone: http://eurekaA:1111/eureka
instance:
hostname: eurekaB #取一个别名
2、host转换
在hosts文件中加入如下配置

4、打包启动
依次执行下面命令
#打包
mvn clean package
# 分别以peer1和peeer2 配置信息启动eureka
java -jar eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=a
java -jar eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=b
启动成功后,就可以看到,两个服务之间互相注册,成为一个集群!
eureka集群使用
在生产中我们可能需要三台或者大于三台的注册中心来保证服务的稳定性,配置的原理其实都一样,将注册中心分别指向其它的注册中心。这里只介绍三台集群的配置情况,其实和双节点的注册中心类似,每台注册中心分别又指向其它两个节点即可,使用application.yml来配置。
application.yml配置详情如下:
---
spring:
application:
name: spring-cloud-eureka
profiles: peer1
server:
port: 8000
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2:8001/eureka/,http://peer3:8002/eureka/
---
spring:
application:
name: spring-cloud-eureka
profiles: peer2
server:
port: 8001
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1:8000/eureka/,http://peer3:8002/eureka/
---
spring:
application:
name: spring-cloud-eureka
profiles: peer3
server:
port: 8002
eureka:
instance:
hostname: peer3
client:
serviceUrl:
defaultZone: http://peer1:8000/eureka/,http://peer2:8001/eureka/
分别以peer1、peer2、peer3的配置参数启动eureka注册中心。
java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer3
Eureka 工作细节
Eureka 本身可以分为两大部分,Eureka Server 和 Eureka Client
Eureka Server
Eureka Server 主要对外提供了三个功能:
- 服务注册,所有的服务都注册到 Eureka Server 上面来
- 提供注册表,注册表就是所有注册上来服务的一个列表,Eureka Client 在调用服务时,需要获取这个注册表,一般来说,这个注册表会缓存下来,如果缓存失效,则直接获取最新的注册表
- 同步状态,Eureka Client 通过注册、心跳等机制,和 Eureka Server 同步当前客户端的状态
Eureka Client
Eureka Client 主要是用来简化每一个服务和 Eureka Server 之间的交互。Eureka Client 会自动拉取、更新以及缓存 Eureka Server 中的信息,这样,即使 Eureka Server 所有节点都宕机,Eureka Client 依然能够获取到想要调用服务的地址(但是地址可能不准确)。
服务注册
服务提供者将自己注册到服务注册中心(Eureka Server),需要注意,所谓的服务提供者,只是一个业务上上的划分,本质上他就是一个 Eureka Client。当 Eureka Client 向 Eureka Server 注册时,他需要提供自身的一些元数据信息,例如 IP 地址、端口、名称、运行状态等等。
服务续约
Eureka Client 注册到 Eureka Server 上之后,事情没有结束,刚刚开始而已。注册成功后,默认情况下,Eureka CLient 每隔 30 秒就要向 Eureka Server 发送一条心跳消息,来告诉 Eureka Server 我还在运行。如果 Eureka Server 连续 90 秒都有没有收到 Eureka Client 的续约消息(连续三次没发送),它会认为 Eureka Client 已经掉线了,会将掉线的 Eureka Client 从当前的服务注册列表中剔除。
服务续约,有两个相关的属性(一般不建议修改):
eureka.instance.lease-renewal-interval-in-seconds=30
eureka.instance.lease-expiration-duration-in-seconds=90
-
eureka.instance.lease-renewal-interval-in-seconds
表示服务的续约时间,默认是 30 秒 -
eureka.instance.lease-expiration-duration-in-seconds
服务失效时间,默认是 90 秒
服务下线
当 Eureka Client 下线时,它会主动发送一条消息,告诉 Eureka Server ,我下线啦。
获取注册表信息
Eureka Client 从 Eureka Server 上获取服务的注册信息,并将其缓存在本地。本地客户端,在需要调用远程服务时,会从该信息中查找远程服务所对应的 IP 地址、端口等信息。Eureka Client 上缓存的服务注册信息会定期更新(30 秒),如果 Eureka Server 返回的注册表信息与本地缓存的注册表信息不同的话,Eureka Client 会自动处理。
这里,也涉及到两个属性,一个是是否允许获取注册表信息:
eureka.client.fetch-registry=true
Eureka Client 上缓存的服务注册信息,定期更新的时间间隔,默认30秒
eureka.client.registry-fetch-interval-seconds=30