Eureka 是 Netflix 开源的注册中心组件,用于集成到 Spring Boot 应用程序。开发者们使用该组件只需要添加一些简单的配置就可以快速启用,构建出大型分布式微服务系统。一个复杂的分布式微服务系统通常会由成百上千个 Spring Boot 应用程序组成,如果尝试手动配置每个程序的服务注册与发现,是非常苦难的,并且扩展性很低,所以服务发现是微服务体系结构的不可缺少的一部分。
Eureka 是用一种 CS 架构,分为 Eureka Server(服务端、注册中心) 和 Eureka Client(客户端)。微服务通过嵌入 Eureka 客户端向 Eureka 服务端注册,注册完成之后各个服务之间就可以相互发现,发起远程调用。客户端向 Eureka 注册时,它将提供有关自身的元数据,例如主机,端口,运行状况指示器 URL,主页和其他详细信息。 Eureka 注册中心接收每一个客户端服务的心跳数据, 默认 Eureka 客户端也就是微服务,每隔 30 秒会主动发送一个服务续约的心跳数据,如果 Eureka 注册中心在 90 秒内没有收到服务的续约,就会认为该服务已经不可用(宕机、关闭),主动将服务信息删除,让其下线。Eureka 结构图如下:
Eureka 服务端本身也是一个 Spring Boot 应用程序,为了让 Eureka 集成到我们的 Spring Boot 应用程序,我们需要在 POM 中加入 spring-cloud-starter-netflix-eureka-server 的依赖:
<!--spring boot 相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Eureka 服务端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
由于 JDK 11 删除了 Eureka 服务端依赖的 JAXB 模块。所以如果你使用的 JDK 版本为 JDK 11 ,则必须在 POM 文件中加入以下依赖项:
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
由于 Eureka 包含了服务端和客户端,对于单机模式下,为了避免 Eureka 因执行自我注册等客户端行为而导致的出错,我们在 application.yml 文件配置 eureka 时,通常需要关闭这些客户端行为:
server:
port: 7001
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false #关闭客户端行为
fetchRegistry: false #关闭客户端行为
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
为了启用 Eureka 服务端我们需要在应用程序启动类使用注解 @EnableEurekaServer 进行声明:
@EnableEurekaServer //启用Eureka服务端
@SpringBootApplication
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class,args);
}
}
启动 Eureka 服务端程序之后,可以在浏览器输入地址 http://localhost:7001 打开 Eureka 管理台:
Spring Boot 应用程序为了集成 Eureka 客户端,我们需要在 POM 中加入 spring-cloud-starter-netflix-eureka-client 依赖:
<dependencies>
<!--spring boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
在配置文件 application.yml 文件中加入连接 Eureka 服务端相关配置:
server:
port: 8088
spring:
application:
name: cloud-eureka-client
#连接Eureka注册中心
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
客户端程序启动类需要加入 @EnableDiscoveryClient 或者 @EnableEurekaClient ,启用 Eureka 客户端:
@SpringBootApplication
@EnableDiscoveryClient //启用Eureka客户端
public class EurekaClientMain8088 {
public static void main(String[] args) {
SpringApplication.run(EurekaClientMain8088.class,args);
}
}
启动程序可以在控制台看到服务注册到 Eureka 的相关日志:
2020-04-19 17:04:07.199 INFO 56748 --- [ main] o.s.c.n.e.s.EurekaServiceRegistry : Registering application CLOUD-EUREKA-CLIENT with eureka with status UP
2020-04-19 17:04:07.199 INFO 56748 --- [ main] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=1587287047199, current=UP, previous=STARTING]
2020-04-19 17:04:07.199 INFO 56748 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_CLOUD-EUREKA-CLIENT/PC-20180401RVMG:cloud-eureka-client:8088: registering service...
再次刷新 Eureka 服务端管理台可以看到注册上来的服务:
我们使用 Spring Boot 应用程序集成 Eureka 客户端的时候,既可以使用 @EnableDiscoveryClient 又可以使用 @EnableEurekaClient ,并且使用方式都是相同的,那么他们有什么区别呢?
Spring Cloud 定义了服务发现 discovery service 的标准,其他第三方注册中心组件只需要实现该标准,就可以具备成为 Spring Cloud 注册中心的能力,例如 eureka、consul、zookeeper、nacos 等。@EnableDiscoveryClient 是 Spring Cloud 标准的服务发现注解,而 @EnableEurekaClient 是 netflix eureka 自己的服务发现注解,从他们所在的 jar 包就可以看出区别:@EnableDiscoveryClient 基于 spring-cloud-commons , 而 @EnableEurekaClient 基于spring-cloud-netflix。由于 netflix eureka 实现了该标准所以使用上并没有多大的区别。推荐使用@EnableDiscoveryClient 注解,因为它是 Spring Cloud 官方的标准注解,可以让 Spring Cloud 客户端程序自由地切换注册中心,而不需要修改启动类的服务发现注解。