SpringCloud学习(三)(服务注册和发现Eureka)
什么是Eureka
Eureka是一个用于服务注册和发现的组件。分为Eureka Server(服务注册中心)和Eureka Client(客户端)。
为什么选择Eureka
在SpringCloud中,可选择Consul、Zookeeper和Eureka作为服务注册和发现的组件,选择Eureka的原因为:
(1)Eureka完全开源,功能和性能经过长时间的版本迭代十分稳定。
(2)Eureka是SpringCloud首选推荐的服务注册和发现组件,与SpringCloud其他组件可以无缝对接。
Eureka的基本架构
主要分为以下三种角色:
(1)Register Service:服务注册中心,它是一个Eureka Server,提供服务注册和发现的功能。
(2)Provider Service:服务提供者,它是一个Eureka Client,提供服务。
(3)Consumer Service:服务消费者,它是一个Eureka Client,消费服务。
服务消费的基本过程如下:
首先需要一个服务注册中心,服务提供者向服务注册中心注册,将自己的信息(ip、端口号、服务名)通过REST API的形式提交给服务注册中心。同样,服务消费者也需要向服务注册中心注册,同时服务消费者获取一份服务注册列表的信息,该列表包含了所有向服务注册中心注册的服务的信息。获取服务注册列表的信息之后,服务消费者就知道服务提供者的ip和端口等信息,可以通过http远程调度来消费服务提供者的服务。
Eureka的一些概念
(1)Register-服务注册
当Eureka Client向Eureka Server注册时,Eureka Client提供自身的元数据(ip、端口、运行状况指标的Url、主页地址等)
(2)Renew-服务续约
Eureka Client默认每隔30s发送一次心跳来进行服务续约。通过服务续约来告知Eureka Server该Eureka Client仍然可用,没有故障。在正常情况下,如果连续90s没有收到心跳,Eureka Server会将Eureka Client实例从注册列表中删除。
(3)Fetch Registries-获取服务注册列表信息
Eureka Client从Eureka Server获取服务注册表信息,并将其缓存在本地。Eureka Client会使用服务注册列表信息查找其他服务的信息,从而进行远程调用。该注册列表信息定时(30s)更新一次,每次返回注册列表信息可能与Eureka Client的缓存信息不同,Eureka Client会自己处理这些信息。如果某种原因导致注册列表信息与Eureka Client的缓存信息不能及时匹配,Eureka Client会重新获取整个注册表信息。Eureka Server缓存了所有的服务注册列表信息,并将整个注册列表以及每个应用程序的信息压缩,压缩内容和没有压缩的内容完全相同。Eureka Client和Eureka Server可以使用JSON和XML的数据格式进行通讯。默认情况下,Eureka Client使用JSON格式的方式来获取服务注册列表的信息。
(4)Cancel-服务下线
Eureka Client在程序关闭时可以向Eureka Server发送下线请求。发送请求后,该客户端的实例信息将从Eureka Server的服务注册列表中删除。该下线请求不会自动完成,需要在程序关闭时调用以下代码。
DisvoveryManager.getInstance().shutdownComponent();
(5)Eviction-服务剔除
在默认情况下,当Eureka Client连续90s没有向Eureka Server发送服务续约(心跳),Eureka Server会将该服务实例从服务注册列表删除,即服务剔除。
编写Eureka Server
首先这里采用的是Maven多Module的结构(先创建一个Maven项目,之后在这个项目上右键新建多个Module)
项目结构
主maven工程pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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"> <modelVersion>4.0.0</modelVersion> <!--这里要注意,两个子工程中会继承主maven工程的pom文件--> <groupId>com</groupId> <artifactId>tm</artifactId> <version>1.0-SNAPSHOT</version> <name>tm</name> <packaging>pom</packaging> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version> <java.version>1.8</java.version> </properties> <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> </project>
之后创建子工程的module工程,命名为eureka-server。采用Spring Initializr的方式创建,作为服务注册中心Eureka Server的工程
子工程pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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"> <modelVersion>4.0.0</modelVersion> <!--这里是和主工程对应的--> <parent> <groupId>com</groupId> <artifactId>tm</artifactId> <version>1.0-SNAPSHOT</version> <relativePath/> </parent> <groupId>com</groupId> <artifactId>eurekaserver</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eurekaserver</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--Eureka Server的起步依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!--springboot测试的起步依赖--> <dependency> <groupId>org.springframework.boot</groupId>--> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <!--springboot的maven插件,有了该插件,即可以使用maven插件的方式来启动springboot工程了--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
之后修改子工程application.properties文件为application.yml,并添加内容
application.yml
其中:
server.port为设置端口号
eureka.instance.prefer-ip-address设置为true,即提交ip信息。
默认情况下,eureka Server会向自己注册,这时需要配置eureka.client.registerWithEureka和eureka.client.fetchRegistry为false,防止自己注册自己。
server:
port: 8761
eureka:
instance:
prefer-ip-address: true
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone:
http://${eureka.instance.hostname}:${server.port}/eureka/
工程类上面加上注解@EnableEurekaServer,开启Eureka Server的功能
EurekaserverApplication(名称不固定,常用格式为xxxApplication)
package com.eurekaserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; import org.springframework.scheduling.annotation.EnableScheduling; @EnableEurekaServer @SpringBootApplication public class EurekaserverApplication { public static void main(String[] args) { SpringApplication.run(EurekaserverApplication.class, args); } }
到目前为止,Eureka Server的搭建工作已经完成,启动程序启动类EurekaserverApplication的main方法,之后浏览器中输入http://localhost:8761/,可以看到,没有注册的实例,这是正常的,等我们创建了Eureka Client之后就有了
编写Eureka Client
在上面创建主maven的基础上,在主maven项目上继续右键创建module,命名为eureka-client,该工程作为Eureka Client向服务注册中心Eureka server注册。
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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"> <modelVersion>4.0.0</modelVersion> <!--这里是继承主maven项目--> <parent> <groupId>com</groupId> <artifactId>tm</artifactId> <version>1.0-SNAPSHOT</version> <relativePath/> </parent> <groupId>com</groupId> <artifactId>eurekaclient</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eurekaclient</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--eureka client所需的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--web功能的起步依赖--> <dependency> <groupId>org.springframework.boot</groupId>--> <artifactId>spring-boot-starter-web</artifactId>--> </dependency> <!--springboot测试的起步依赖--> <dependency> <groupId>org.springframework.boot</groupId>--> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.yml
这里的defaultZone是指Eureka Server的注册地址
eureka:
client:
service-url:
defaultZone:
http://localhost:8761/eureka/
server:
port: 8762
spring:
application:
name:eureka-client
启动类EurekaclientApplication加上注解@EnableEurekaClient开启Eureka Client功能
EurekaclientApplication
package com.eurekaclient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableEurekaClient @SpringBootApplication public class EurekaclientApplication { public static void main(String[] args) { SpringApplication.run(EurekaclientApplication.class, args); } }
启动EurekaclientApplication里的main方法,浏览器中输入http://localhost:8761/(Eureka Server项目也要启动),可以看到Eureka Client已经向Eureka Server注册了。
并且从控制台也可以看出注册了
参考:《深入理解Spring Cloud与微服务构建(第二版)》方志朋著
本篇文章仅用于个人学习,如有侵权,联系必删!
持续更新!!!