1.Eureka是什么

Eureka 是 Netflix 公司开发的一款开源的服务注册与发现组件。可以理解为SpringCloudNetflix微服务框架中的服务注册中心

2.注册中心是什么

在最初的架构体系中,集群的概念还不那么流行,且机器数量也比较少,此时直接使用DNS+Nginx就可以满足几乎所有RESTful服务的发现。相关的注册信息直接配置在Nginx。但是随着微服务的流行与流量的激增,机器规模逐渐变大,并且机器会有频繁的上下线行为,这种时候需要运维手动地去维护这个配置信息是一个很麻烦的操作。所以开发者们开始希望有这么一个东西,它能维护一个服务列表,哪个机器上线了,哪个机器宕机了,这些信息都会自动更新到服务列表上,客户端拿到这个列表,直接进行服务调用即可。这个就是注册中心的作用

3.CAP理论

CAP理论是分布式系统中一个很重要的理论,它描述的是一个分布式系统最多只能满足CAP中的两个条件,不可能同时满足三个条件

  1. C(Consistency):强一致性。保证在一定时间内,集群中的各个节点的状态会达到较强的一致性,同时,为了达到这一点,一般会牺牲一点响应时间。而放弃C也不意味着放弃一致性,而是放弃强一致性。允许系统内有一定的数据不一致情况的存在
  2. A (Avalibility):高可用性。意味着系统一直处于可用状态。个别节点的故障不会影响整个服务的运作
  3. P(Partition Tolerance):分区容忍性。当系统出现网络分区等情况时,依然能对外提供服务。想到达到这一点,一般来说会把数据复制到多个分区里,来提高分区容忍性。这个一般是不会被抛弃的

    4.热门注册中心对比

    | 对比项目 | Nacos | Eureka | Consul | CoreDNS | Zookeeper | | —- | —- | —- | —- | —- | —- | | 一致性协议 | CP+AP | AP | CP | — | CP | | 健康检查 | TCP/HTTP/MYSQL/Client Beat | Client Beat | TCP/HTTP/gRPC/Cmd | — | Keep Alive | | 负载均衡策略 | 权重/metadata/Selector | Ribbon | Fabio | RoundRobin | — | | 雪崩保护 | 有 | 有 | 无 | 无 | 无 | | 自动注销实例 | 支持 | 支持 | 不支持 | 不支持 | 支持 | | 访问协议 | HTTP/DNS | HTTP | HTTP/DNS | DNS | TCP | | 监听支持 | 支持 | 支持 | 支持 | 不支持 | 支持 | | 多数据中心 | 支持 | 支持 | 支持 | 不支持 | 不支持 | | 跨注册中心同步 | 支持 | 不支持 | 支持 | 不支持 | 不支持 | | SpringCloud集成 | 支持 | 支持 | 支持 | 不支持 | 不支持 | | Dubbo集成 | 支持 | 不支持 | 不支持 | 不支持 | 支持 | | K8S集成 | 支持 | 不支持 | 支持 | 支持 | 不支持 |

5.Eureka两大组件

Eureka 采用 CS(Client/Server,客户端/服务器) 架构,它包括以下两大组件:

  • Eureka Server:Eureka 服务注册中心,主要用于提供服务注册功能。当微服务启动时,会将自己的服务注册到 Eureka Server。Eureka Server 维护了一个可用服务列表,存储了所有注册到 Eureka Server 的可用服务的信息,这些可用服务可以在 Eureka Server 的管理界面中直观看到。
  • Eureka Client:Eureka 客户端,通常指的是微服务系统中各个微服务,主要用于和 Eureka Server 进行交互。在微服务应用启动后,Eureka Client 会向 Eureka Server 发送心跳(默认周期为 30 秒)。若 Eureka Server 在多个心跳周期内没有接收到某个 Eureka Client 的心跳,Eureka Server 将它从可用服务列表中移除(默认 90 秒)。

注:“心跳”指的是一段定时发送的自定义信息,让对方知道自己“存活”,以确保连接的有效性。大部分 CS 架构的应用程序都采用了心跳机制,服务端和客户端都可以发心跳。通常情况下是客户端向服务器端发送心跳包,服务端用于判断客户端是否在线。

6.Eureka服务的注册与发现

image.png
上图中共涉及到以下 3 个角色:

  • 服务注册中心(Register Service):它是一个 Eureka Server,用于提供服务注册和发现功能。
  • 服务提供者(Provider Service):它是一个 Eureka Client,用于提供服务。它将自己提供的服务注册到服务注册中心,以供服务消费者发现。
  • 服务消费者(Consumer Service):它是一个 Eureka Client,用于消费服务。它可以从服务注册中心获取服务列表,调用所需的服务。

Eureka 实现服务注册与发现的流程如下:

  1. 搭建一个 Eureka Server 作为服务注册中心;
  2. 服务提供者 Eureka Client 启动时,会把当前服务器的信息以服务名(spring.application.name)的方式注册到服务注册中心;
  3. 服务消费者 Eureka Client 启动时,也会向服务注册中心注册;
  4. 服务消费者还会获取一份可用服务列表,该列表中包含了所有注册到服务注册中心的服务信息(包括服务提供者和自身的信息);
  5. 在获得了可用服务列表后,服务消费者通过 HTTP 或消息中间件远程调用服务提供者提供的服务。
    服务注册中心(Eureka Server)所扮演的角色十分重要,它是服务提供者和服务消费者之间的桥梁。服务提供者只有将自己的服务注册到服务注册中心才可能被服务消费者调用,而服务消费者也只有通过服务注册中心获取可用服务列表后,才能调用所需的服务。

    7.项目实战

    参考:点击这里

    8.eureka单机版常用配置说明

    1.eureka server

    ```powershell org.springframework.boot spring-boot-starter-web
org.springframework.cloud spring-cloud-starter-netflix-eureka-server ```java @SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } } powershell server: port: 1001 #该 Module 的端口号 #eureka配置 eureka: instance: hostname: localhost #eureka服务端的实例名称, prefer-ip-address: true #显示访问路径的 ip 地址 lease-expiration-duration-in-seconds: 15 #服务过期时间,如果超过这个时间没有检测到心跳,就将这个实例剔除 lease-renewal-interval-in-seconds: 5 #client发送心跳给server端的频率 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机版服务注册中心 ### 2.eureka client powershell <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> java @SpringBootApplication @EnableEurekaClient public class Service1Application { public static void main(String[] args) { SpringApplication.run(Service1Application.class, args); } } powershell server: port: 1002 #服务端口号 spring: application: name: service1 #微服务名称,对外暴漏的微服务名称,十分重要 eureka: instance: instance-id: spring-cloud-service1 #自定义服务名称信息 prefer-ip-address: true #显示访问路径的 ip 地址 lease-expiration-duration-in-seconds: 15 #服务过期时间,如果超过这个时间没有检测到心跳,就将这个实例剔除 lease-renewal-interval-in-seconds: 5 #client发送心跳给server端的频率 client: #将客户端注册到 eureka 服务列表内 service-url: defaultZone: http://localhost:1001/eureka #这个地址是 7001注册中心在 application.yml 中暴露出来额注册地址 (单机版) PS:prefer-ip-address参数可以在鼠标放在对应服务上时,在左下角显示ip以及端口号
image.png ## 8.eureka集群版常用配置说明 需要先修改host文件
#Spring Cloud eureka 集群
127.0.0.1 eureka1001.com
127.0.0.1 eureka2001.com ### 1.eureka server节点1 ```powershell org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-server ```java @SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } } powershell server: port: 1001 #该 Module 的端口号 #eureka配置 eureka: instance: hostname: eureka1001.com #eureka服务端的实例名称, prefer-ip-address: true #显示访问路径的 ip 地址 lease-expiration-duration-in-seconds: 15 #服务过期时间,如果超过这个时间没有检测到心跳,就将这个实例剔除 lease-renewal-interval-in-seconds: 5 #client发送心跳给server端的频率 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://eureka2001.com:2001/eureka/ #将当前注册中心注册到另一个服务注册中心 ### 2.eureka server节点2 ```powershell org.springframework.boot spring-boot-starter-web

org.springframework.cloud spring-cloud-starter-netflix-eureka-server

  1. ```java
  2. @SpringBootApplication
  3. @EnableEurekaServer
  4. public class EurekaApplication {
  5. public static void main(String[] args) {
  6. SpringApplication.run(EurekaApplication.class, args);
  7. }
  8. }
  1. server:
  2. port: 2001 #该 Module 的端口号
  3. #eureka配置
  4. eureka:
  5. instance:
  6. hostname: eureka2001.com #eureka服务端的实例名称,
  7. prefer-ip-address: true #显示访问路径的 ip 地址
  8. lease-expiration-duration-in-seconds: 15 #服务过期时间,如果超过这个时间没有检测到心跳,就将这个实例剔除
  9. lease-renewal-interval-in-seconds: 5 #client发送心跳给server端的频率
  10. client:
  11. register-with-eureka: false #false表示不向注册中心注册自己。
  12. fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
  13. service-url:
  14. defaultZone: http://eureka1001.com:1001/eureka/ #将当前注册中心注册到另一个服务注册中心

2.eureka client

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  8. </dependency>
  1. @SpringBootApplication
  2. @EnableEurekaClient
  3. public class Service1Application {
  4. public static void main(String[] args) {
  5. SpringApplication.run(Service1Application.class, args);
  6. }
  7. }
  1. server:
  2. port: 1002 #服务端口号
  3. spring:
  4. application:
  5. name: service1 #微服务名称,对外暴漏的微服务名称,十分重要
  6. eureka:
  7. instance:
  8. instance-id: spring-cloud-service1 #自定义服务名称信息
  9. prefer-ip-address: true #显示访问路径的 ip 地址
  10. lease-expiration-duration-in-seconds: 15 #服务过期时间,如果超过这个时间没有检测到心跳,就将这个实例剔除
  11. lease-renewal-interval-in-seconds: 5 #client发送心跳给server端的频率
  12. client: #将客户端注册到 eureka 服务列表内
  13. service-url:
  14. defaultZone: http://eureka1001.com:1001/eureka/,http://eureka2001.com:2001/eureka/ #将服务注册到eureka集群

image.png
image.png

9.Eureka自我保护机制

当我们在本地调试基于 Eureka 的程序时,Eureka 服务注册中心很有可能会出现如下图所示的红色警告。
image.png
实际上,这个警告是触发了 Eureka 的自我保护机制而出现的。默认情况下,如果 Eureka Server 在一段时间内(默认为 90 秒)没有接收到某个服务提供者(Eureka Client)的心跳,就会将这个服务提供者提供的服务从服务注册表中移除。 这样服务消费者就再也无法从服务注册中心中获取到这个服务了,更无法调用该服务。
但在实际的分布式微服务系统中,健康的服务(Eureka Client)也有可能会由于网络故障(例如网络延迟、卡顿、拥挤等原因)而无法与 Eureka Server 正常通讯。若此时 Eureka Server 因为没有接收心跳而误将健康的服务从服务列表中移除,这显然是不合理的。而 Eureka 的自我保护机制就是来解决此问题的。
所谓 “Eureka 的自我保护机制”,其中心思想就是“好死不如赖活着”。如果 Eureka Server 在一段时间内没有接收到 Eureka Client 的心跳,那么 Eureka Server 就会开启自我保护模式,将所有的 Eureka Client 的注册信息保护起来,而不是直接从服务注册表中移除。一旦网络恢复,这些 Eureka Client 提供的服务还可以继续被服务消费者消费
综上,Eureka 的自我保护机制是一种应对网络异常的安全保护措施。它的架构哲学是:宁可同时保留所有微服务(健康的服务和不健康的服务都会保留)也不盲目移除任何健康的服务。通过 Eureka 的自我保护机制,可以让 Eureka Server 集群更加的健壮、稳定。
可以通过修改eureka.server.enable-self-preservation为false关闭自我保护机制
Eureka 的自我保护机制也存在弊端。如果在 Eureka 自我保护机制触发期间,服务提供者提供的服务出现问题,那么服务消费者就很容易获取到已经不存在的服务进而出现调用失败的情况,此时,我们可以通过客户端的容错机制来解决此问题,详情请参考 Spring Cloud Netflix RibbonSpring Cloud Netflix Hystrix

10.eureka常用参数

1.eureka.client.registry-fetch-interval-seconds

eureka client拉取服务列表间隔时间(默认单位秒)
表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒

2.eureka.instance.lease-expiration-duration-in-seconds

eureka client/server有效心跳间隔时间(默认单位秒)
leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance。默认为90秒
如果该值太大,则很可能将流量转发过去的时候,该instance已经不存活了。
如果该值设置太小了,则instance则很可能因为临时的网络抖动而被摘除掉(在自我保护模式关闭的情况下)。
该值至少应该大于leaseRenewalIntervalInSeconds

3.eureka.instance.lease-renewal-interval-in-seconds

eureka client/server发送心跳间隔时间(默认单位秒)
leaseRenewalIntervalInSeconds,表示eureka client发送心跳给server端的频率。如果在leaseExpirationDurationInSeconds后,server端没有收到client的心跳,则将摘除该instance。除此之外,如果该instance实现了HealthCheckCallback,并决定让自己unavailable的话,则该instance也不会接收到流量。
默认30秒

4.eureka.server.enable-self-preservation

eureka server是否开启自我保护模式,默认为true。

5.eureka.server.eviction-interval-timer-in-ms

eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒