Eureka是Netflix开源的一款提供服务注册和发现的组件,它提供了完整的Service Registry和Service Discovery实现。也是springcloud体系中最重要最核心的组件之一。
Eureka 分为Eureka Server(服务端) 和 Eureka Client(客户端)
Eureka 优点:
主要包括以下3个角色
原理:
Register–服务注册
当Eureka Client 向Eureka Server 注册时,Eureka Client 提供自身的元数据,比如IP地址、端口’运行状况指标的url、主页地址等信息
Renew–服务续约
当Eureka Client 在默认情况下每隔30秒发送一次心跳来进行服务续约,来表明该Eureka Client可以正常使用
如果,Eureka Server 在90秒内没收到Eureka Client 的心跳,Eureka Server便会将Eureka Client 实例从注册列表中移除。注意:官方建议不要更改服务续约的间隔时间
Fetch Registries–获取注册列表
Eureka Client从Eureka Server 获取服务注册列表信息,并将其缓存在本地。Eureka Client会使用服务注册列表信息查找其他服务的信息,从而进行远程调用。
Eureka Client通过适应JSON 和XML 数据格式与Eureka Server通信。默认使用JSON 格式获取服务注册列表信息
Cancel --服务下线
Eureka Client 在关闭时可以向Eureka Service 发送下线请求,在发送请求后,该Eureka Client实例信息将从Eureka Server 的服务注册列表中删除。
该下线请求不能自动完成,需要在程序关闭时调用一下代码
DiscoveryManager.getInstance().shutdownComponent();
Evuction-- 服务剔除
默认情况下,Eureka Server 在90秒内没收到Eureka Client 的心跳,Eureka Server便会将Eureka Client 实例从注册列表中移除
Eureka Server 的响应缓存
Eureka Server维护默认每30秒更新一次响应缓存,所以即使刚刚注册的实例,也不会立即出现在服务注册列表中
Eureka client 的注册延迟
Eureka client 启动后不会立即注册,有个延迟时间,如果跟踪代码会发现延迟时间为40秒,源码在eureka-client-1.6.2.jar的DefaultEurekaClientConfig类中,代码如下:
public int getInitialInstanceInfoReplicationIntervalseconds(){
return configInstance.getIntProperty(
namespace + INITIAL_REGISTRATION_REPLICATION_DELAT_KEY,40).get();
}
Eureka Client 的缓存
Eureka Client 保留注册表信息的缓存,该缓存每30秒更一次,因此,Eureka Client 刷新本地缓存,并发现其他新注册的实例可能需要30秒
LoadBalancer 的缓存
Ribbon 的负载平衡器从本地的Eureka Client 获取服务注册列表信息。Ribbon 本身还维护了缓存,以避免每个请求都需要从Eureka Client 获取服务注册列表。此缓存每30秒刷新一次,所以至少需要30秒才能使用新注册的实例
当有一个新的Eureka Server 出现时,它会尝试从相邻的Peer 节点获取所有服务实例注册表信息。
如果相邻的Peer 节点获取信息时出现故障,Eureka Server 会尝试其他的Peer 节点,在成功获取所有的服务实例信息后,会根据配置信息设置服务续约的阀值。
如果,在任何时间Eureka Server 接收到的服务续约低于该值配置的百分比(默认15分钟内低于85%),则服务器开启自我保护模式,即不再剔除注册列表的信息。
这样的好处:如Eureka Server 自身网络问题导致Eureka Client 无法续约,Eureka Client 的注册表信息不再被删除,还可以被其他服务消费
默认Eureka Server 自我保护模式,如果需要关闭,需要如下配置:
eureka.server.enable-self-preservation=false
微服务一般采用 Maven 多 module 结构。所以我们需要创建一个maven主工程
结构如下:
springcloud-eureka
|__eureka-server
|__eureka-client
主工程项目springcloud-eureka的 pom 文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.husygroupId>
<artifactId>springcloud-eurekaartifactId>
<packaging>pompackaging>
<version>1.0-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.9.RELEASEversion>
<relativePath/>
parent>
<properties>
<java.version>1.8java.version>
<spring-cloud.version>Greenwich.SR3spring-cloud.version>
properties>
<modules>
<module>eureka-servermodule>
<module>eureka-clientmodule>
modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
project>
1、pom文件配置
springcloud 已集成了Eureka 服务器,只需要引用spring-cloud-starter-netflix-eureka-server
依赖即可
。在很多博文和文章中都引用的是spring-cloud-starter-eureka-server
,这里需要说明一下,spring-cloud-starter-eureka-server
是之前的版本,官方推荐使用的是前者。
所以,我们pom 文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.husygroupId>
<artifactId>springcloud-eurekaartifactId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>eureka-serverartifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
2、配置文件
在默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为。
这里使用的是application.yml,如下:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
# 表示是否将自己注册到Eureka Server,默认为true
registerWithEureka: false
# 表示是否从Eureka Server获取注册信息,默认为true。
fetchRegistry: false
serviceUrl:
# 设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址。
# 默认是http://localhost:8761/eureka ;多个地址可使用 , 分隔。
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3、启动类
添加启动代码中添加@EnableEurekaServer
注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
ok,Eureka Server 初步搭建完成。启动工程后,访问:http://localhost:8761/eureka ,可以看到下面的页面,其中还没有发现任何服务
1、pom文件
客户端需要引用spring-cloud-starter-netflix-eureka-client
和spring-boot-starter-web
依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.husygroupId>
<artifactId>springcloud-eurekaartifactId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>eureka-clientartifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
2、配置文件
spring:
application:
name: eureka-client
server:
port: 8762
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
3、 客户端代码
@SpringBootApplication
@RestController
@EnableEurekaClient
public class EurekaClientApplication {
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
启动后,我们重新访问服务端页面:http://localhost:8761/eureka ,如下:
我们可以看到有一个服务已经注册了。
在微服务项目中,Eureka Server 的作用举足轻重,如果单服务的话,遇到故障或毁灭性问题。那整个项目将停止运行。因此对Eureka 进行高可用集群是非常必要的
这里只介绍三台集群的配置情况,每台注册中心分别又指向其它两个节点即可,修改pom 文件。
1、pom 文件
---
spring:
profiles: peer1
server:
port: 8001
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2:8002/eureka/,http://peer3:8003/eureka/
---
spring:
profiles: peer2
server:
port: 8002
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1:8001/eureka/,http://peer3:8003/eureka/
---
spring:
profiles: peer3
server:
port: 8003
eureka:
instance:
hostname: peer3
client:
serviceUrl:
defaultZone: http://peer1:8001/eureka/,http://peer2:8002/eureka/
本地搭建Eureka Server 集群,需要修改 host 文件,我的在C:\Windows\System32\drivers\etc目录下
在文件最后加上以下代码:
127.0.0.1 peer1
127.0.0.1 peer2
127.0.0.1 peer3
打包编译后,用 java -jar
启动 ,方式如下
java -jar eureka-server-1.0-SNAPSHOT.jar --spring.profiles.active=peer1 java -jar eureka-server-1.0-SNAPSHOT.jar --spring.profiles.active=peer2 java -jar eureka-server-1.0-SNAPSHOT.jar --spring.profiles.active=peer3
依次启动完成后,浏览器输入:http://localhost:8001/
效果图如下:
注意:
这正常现象,只要启动完3个服务后,就不会报错了。小伙伴们不要慌。
修改 Eureka Client的配置文件,修改如下:
server:
port: 8101
spring:
application:
name: eureka-client
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8001/eureka/
启动项目,再次浏览器输入:http://localhost:8001/
GitHub代码