一:简介
- 什么是Eureka?
和Consul,Zookeeper类似,Eureka是一个用于服务注册和发现的组件。它分为Eureka Server和Eureka Client,
Eureka Server为Eureka服务注册中心,Eureka Client为Eureka客户端。 - 为什么选择Eureka?
首先Eureka完全开源,是Netflix公司的开源产品,经历了Netflix公司的生产环境考验,以及几年时间的不断迭代,
在功能和性能上都非常稳定,可以放心的使用。
其次Eureka是Spring Cloud首选推荐的服务注册和发现组件,可以与Spring Cloud其他的组件完成无缝对接。
最后,Eureka和其它组件,比如负载均衡组件Ribbon,熔断器组件Hystrix,熔断器监控组件Hystrix DashBoard
组件以及网关Zuul组件相互配合,能够轻松实现服务注册,负载均衡,熔断和只能路由等功能。 - Eureka的基本架构
⑴主要包含以下3种角色
a:Register Service,服务注册中心,它是一个Eureka Server,提供服务注册和发现的功能。
b:Provider Service,服务提供者,它是一个Eureka Client,提供服务。
c:Consumer Service,服务消费者,它是一个Eureka Client,消费服务。
⑵服务消费的基本过程如下:
首先需要一个服务注册中心Eureka Server,服务提供者Eureka Client向服务注册中心Eureka Server注册,
将自己的信息(比如服务名和服务的IP地址等)通过REST API的形式提交给服务注册中心Eureka Server。
同样,服务消费者Eureka Client也向服务注册中心Eureka Server注册,同时服务消费者获取一份服务注册列表
的信息,该列表包含了所有向服务注册中心Eureka Server注册的服务信息。获取服务注册列表信息之后,服务
消费者就知道服务提供者的IP地址,可以通过HTTP远程调度来消费服务提供者服务。
- Eureka的一些概念
⑴Register,服务注册
当Eureka Client向Eureka Server注册时,Eureka Client提供自身的元数据,比如IP地址,端口,远行状况
指标的Url,主页地址等信息。
⑵Renew,服务续约
Eureka Client在默认的情况下会每隔30秒发送一次心跳来进行服务续约。通过服务续约来告知Eureka Server
该Eureka Client仍然可用,没有出现故障。正常情况下,如果Eureka Server在90秒内没有收到Eureka Client的
心跳,Eureka Server会将Eureka Client实例从注册列表中删除。(注意:官网建议不要更改服务续约的间隔时间.)
⑶Fetch Registries,获取服务注册列表信息
Eureka Client从Eureka Server获取服务注册表信息,并将其缓存在本地。Eureka Client会使用服务注册列表
信息查找其他服务的信息,从而进行远程调用。该注册列表信息定时(每30秒)更新一次,每次Eureka Server
返回给Eureka Client的注册列表信息可能与Eureka Client的缓冲信息不同,Eureka Client自己会处理这些信息。
如果由于某种原因导致注册列表信息不能及时匹配,Eureka Client会重新获取整个注册表信息。Eureka Server
缓存了所有服务注册列表信息,并将整个注册列表以及每个应用程序的信息进行了压缩。Eureka Server和Eureka
Client可以使用JSON和XML数据格式进行通信。在默认的情况下,Eureka Client使用JSON格式的方式来获取服务
注册列表信息。
⑷Cancel,服务下线
Eureka Client在程序关闭时可以向Eureka Server发送下线请求。发送请求后,该客户端的实例信息将从Eureka
Server的服务注册列表中剔除。该下线请求不会自动完成,需要在程序关闭时调用下面代码:
DiscoveryManager.getInstance().shutdownComponent();
⑸Eviction,服务剔除
在默认情况下,当Eureka Client连续90秒没有向Eureka Server发送服务续约(即心跳)时,Eureka Server会
将该服务实例从服务注册列表中删除,即服务剔除。
- 为什么Eureka Client获取服务实例比较慢?
⑴Eureka Client的注册延迟
Eureka Client启动之后,不是立即向Eureka Server注册的,而是有一个延迟向服务端注册的时间。这个时间
默认为40秒。
⑵Eureka Server的响应缓存
Eureka Client保留注册表信息的缓存。该缓存每30秒更新一次。因此Eureka Client刷新本地缓存并发现其他
新注册的实例可能需要30秒。
二:构建高可用的Eureka Server集群案例
- 项目基本架构如下
- 首先看主工厂chapter5-2的pom.xml文件内容
<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.0</modelVersion> <groupId>com.kgf</groupId> <artifactId>chapter5-2</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <name>chapter5-2</name> <!--继承一个父模块,然后再引入相应的依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <!--relativePath是可选的,maven会首先搜索这个地址,在搜索本地远程repositories之前 --> <relativePath /> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java-version>1.8</java-version> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> </properties> <!--下面的方式通过import可以实现多继承的问题 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <modules> <module>eureka-server</module> <module>eureka-client</module> </modules> </project>
- eureka-server工程的结构
⑴application.yml文件
⑵ 启动类EurekaServerApplication.java文件
⑶pom.xml文件
<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.0</modelVersion> <parent> <groupId>com.kgf</groupId> <artifactId>chapter5-2</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>eureka-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-server</name> <dependencies> <!-- 引入eureka-server依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!-- 引入test测试依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope><!--表示仅仅在测试的时候编译 --> </dependency> </dependencies> <build> <plugins> <!--能够将Spring Boot应用打包为可执行的jar或war文件,然后以通常的方式运行Spring Boot应用 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- Eureka-Client工程结构
⑴bootsrap.yml文件
⑵EurekaClientApplication.java启动类
⑶简单web类HiController
⑷pom.xml文件
<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.0</modelVersion> <parent> <groupId>com.kgf</groupId> <artifactId>chapter5-2</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>eureka-client</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-client</name> <dependencies> <!-- 引入eureka依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 引入test测试依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope><!--表示仅仅在测试的时候编译 --> </dependency> </dependencies> </project>
三:启动这个高可用实例
- 注意,在上诉的Eureka-Server工程的yml文件代码中,我们定义了两个profile文件,分别为peer1和peer2,它们的hostname分别为
peer1和peer2.因为是本地搭建的Eureka Server集群,所以需要修改本地hosts文件,
地址为:C:\Windows\System32\drivers\etc,修改内容如下:
127.0.0.1 peer1
127.0.0.1 peer2 - 下面我们还需要通过Maven编译工程,Maven命令为mvn clean package。编译完成后,在工程的目录下会有一个target文件夹,进 入 该文件夹,可以发现生成了一个eureka-server-0.0.1-SNAPSHOT.jar的jar包。我们可以通过java-jar的方式启动工程,并通过
spring.profiles.active指定启动的配置文件。在我们这个例子中需要启动两个Eureka Server,所以命令如下(端口分别为8761,8762):
java -jar eureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar eureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
启动两个Eureka Server如下:
- 最后启动的是Eureka Client工程,端口为8763,并且它仅仅只注册到端口为8761的peer1的Eureka Server中。
- 效果
如上图,可以发现Eureka Client工程端口号为8763已经注册进入Eureka Server了,并且在DS Replicas选项中
显示了节点peer2,但是我们8763这个Eureka Client工程中没有指向peer2节点的Eureka Server注册,那么我们
现在去peer2这个节点看一下,如下:
可以发现Eureka Client已经向peer2节点注册了,说是peer1节点同步到了peer2,完成了高可用的操作。