SpringCloud3️⃣Eureka 注册中心
在一个业务中,服务调用关系中有 2 个角色
- 服务提供者:提供接口,供其它微服务调用。
- 服务消费者:调用其它微服务提供的接口。
角色是相对业务而言的。
即一个微服务既可以是提供者,也可以是消费者。
1、问题引入
假设:服务提供者部署了多个实例
服务消费者发起远程调用时,要考虑以下问题:
-
如何获取服务提供者实例地址的列表?
-
如何从多个实例中选取?
-
如何得知实例是否健康?
注册中心的出现,解决了以上问题。
- Eureka:Netflix
- Nacos:阿里巴巴
2、Eureka 架构
Eureka
是 Netflix 开发的,基于 REST
的服务注册和服务发现框架。
2.1、组件
Eureka Client
:客户端Eureka Server
:服务端
2.1.1、Eureka Client
本质是一个 Java 客户端,简化与 Eureka Server 的交互。
Eureka Client
启动之后:- 向 Eureka Server 发起服务注册。
- 每经过一个心跳周期(默认 30s)向 Eureka Server 发送一次心跳包,表明服务健在(未宕机)。
- 若 Eureka Server 在多个心跳周期(默认 3)没有收到节点的心跳,就会从服务注册表中移除对应节点。
- 角色
- 服务提供者:Service Provider(Application Service)
- 服务消费者:Service Consumer(Application Client)
- 内置负载均衡器,默认使用轮询(round-robin)负载算法。
2.1.2、Eureka Server
-
服务注册
-
各个微服务节点启动后,会在 Eureka Server 中注册。
-
Eureka Server 本身也是服务,默认也会注册到 Eureka Server 中。
-
Eureka Server 的服务注册表中,存储所有可用服务节点的信息。
-
-
Eureka Server 集群
- 集群中每个 Eureka Server 节点的地位平等,同时对外提供服务注册和发现功能。
- 节点之间会通过 Replicate 进行数据同步。
2.2、架构图
-
Eureka Client
- 服务提供者
- Register(服务注册):在 Eureka 注册当前服务的 IP 和端口。
- Renew(服务续约):每 30 秒向 Eureka 发送一次心跳包。
- Cancel(服务下线)
- 服务消费者
- Get Registry(服务发现):获取服务注册列表
- Make Remote Call(远程调用)
- 服务提供者
-
Eureka Server
-
Replicate(集群数据同步):Eureka 集群中,Eureka Server 之间的数据同步。
-
2.3、问题解答
本文最开始的问题引入
-
如何获取服务提供者实例地址的列表?——服务发现
-
如何从多个实例中选取?——负载均衡
-
如何得知实例是否健康?——心跳机制
2.3.1、服务发现
- 服务提供者(Application Service)节点启动后,向 Eureka Server 发起
Register
注册。 - Eureka Server 的服务注册表中,存储所有可用服务节点的信息。
- 服务消费者(Application Client)根据服务名称,向 Eureka Server 发起
Get Registry
拉取实例列表。
2.3.2、负载均衡
- Eureka Client 内置负载均衡器,默认使用轮询(round-robin)负载算法。
- 服务消费者(Application Client)根据负载均衡算法,选取一个实例地址。
2.3.3、心跳机制
-
服务提供者(Application Service)节点每每隔一个心跳周期(默认 30s)向 Eureka Server 发送一次心跳。
-
若 Eureka Server 在多个心跳周期(默认 3)没有收到节点的心跳,就会从服务注册表中移除对应节点。
3、Eureka 搭建
搭建步骤
- Eureka Server:需单独建立一个微服务,作为 Eureka 注册中心。
- Eureka Client:封装了服务注册、服务发现等功能,可配置到已有微服务中。
- 配置 Application Service(服务提供者),注册到 Eureka 中。
- 配置 Application Client(服务消费者),向 Eureka 拉取实例列表,实现远程调用。z
3.1、eureka-server
创建服务:在 cloud-demo 父工程下,创建一个不带模板的 Maven 模块(名称 eureka-server)
3.1.1、配置
-
引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
-
启动类:添加
@EnableEurekaServer
注解,开启 eureka 注册中心功能。@EnableEurekaServer @SpringBootApplication public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }
-
配置文件:
application.yml
-
port:服务端口号
-
name:微服务名称
-
defaultZone
-
注册中心地址,可配置多个(搭建 eureka-server 集群时)
-
eureka-server 本身也是微服务应用,也注册到注册中心。
server: port: 10000 spring: application: name: eureka-server # Eureka注册中心地址 eureka: client: service-url: defaultZone: http://127.0.0.1:10000/eureka
-
-
-
3.1.2、启动
启动微服务,访问 eureka-server
3.2、eureka-client
3.2.1、服务提供者(注册)
将 user-service 注册到
eureka-server
中
配置
-
引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
-
配置文件:
application.yml
,添加以下配置spring: application: name: user-service # Eureka注册中心地址 eureka: client: service-url: defaultZone: http://127.0.0.1:10000/eureka
启动
模拟一个服务部署多个实例的场景
-
复制服务:右键 UserApplication → Copy Configuration,修改服务名,端口号
-
启动服务:查看 Eureka 注册中心,已注册 2 个实例。
3.2.2、服务消费者(发现)
将 order-service 中硬编码的 URL 改成服务名,实现服务发现。
配置
配置内容与服务提供者完全相同
-
引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
-
配置:会将 order-service 注册到 Eureka 中。
spring: application: name: order-service # Eureka注册中心地址 eureka: client: service-url: defaultZone: http://127.0.0.1:10000/eureka
服务发现 & 负载均衡
向 eureka-server 中拉取 user-service 服务的实例列表,并实现负载均衡。
只需要添加一些注解即可。
-
服务发现:用服务名代替硬编码的 IP 地址和端口号
-
负载均衡:注册 RestTemplate 时添加
@LoadBalanced
注解。(原理:Ribbon)
@LoadBalanced @Bean public RestTemplate restTemplate() { return new RestTemplate(); }
启动
-
服务注册:order-service 成功注册到 Eureka 中
-
测试接口:可正常访问