Eureka是Netflix公司开源的一个服务注册与发现组件,类似的组件还有Zookeeper、Consul。
Eureka分为Eureka Server(服务注册中心,每个服务都在这里注册信息,提供服务名、IP、端口等信息)和Eureka Client(客户端) ,Eureka Client又可以分为服务提供者和服务消费者,譬如两个服务都在注册中心注册了,同时服务消费者从注册中心Eureka Server获得一份在注册中心注册的所有服务注册信息,服务消费者就知道了所有服务提供者的IP,通过Http远程调度来消费服务提供者的服务,他们相互之间调用彼此的接口了。这样既是服务的提供者又是服务消费者。
本实例GitHub地址:https://github.com/MistraR/springCloudApplication
一、Eureka Server
此Demo要包含很多Spring Cloud的组件,项目为多model项目,先创建一个Maven工程,作为主工程。然后把src文件夹删除。所有子模块都将继承主工程的pom依赖。使用的依赖几乎都是当前时间(2018-07)的最新版本。
改造主工程的pom依赖:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cloud</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>eurekaclient</module>
<module>eurekaserver</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</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>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<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>
<modules>
<module>eurekaclient</module>
<module>eurekaserver</module>
</modules>
这个是后面新增了model添加进去的
右键项目名称new–>model,通过Spring Initializr快速新建model:eurekaserver。可以在里面勾选上你需要的依赖。
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cloud</groupId>
<artifactId>eurekaserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eurekaserver</name>
<description>Demo project for Spring Boot</description>
<parent>
<!--继承主工程依赖-->
<groupId>com.cloud</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</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>
<dependencies>
<!--eureka server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在应用主类标明Eureka Server注册中心:@EnableEurekaServer
@SpringBootApplication
//启动一个服务注册中心
@EnableEurekaServer
public class EurekaserverApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaserverApplication.class, args);
}
}
在resourses文件下新建application.yml配置文件(更喜欢用yml格式)
server:
# 访问地址 http://localhost:7777/
port: 7777
eureka:
instance:
hostname: localhost
client:
#默认情况下eureka server也是一个eureka client ,必须要指定一个 server。
#通过eureka.client.registerWithEureka:false和fetchRegistry:false来表明自己是一个eureka server.
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
二、Eureka Client
如上面一样新建一个model:eurekaclient
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cloud</groupId>
<artifactId>eurekaclient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eurekaclient</name>
<description>Demo project for Spring Boot</description>
<parent>
<!--继承主工程依赖-->
<groupId>com.cloud</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</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>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
</dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
应用主类上添加注解:@EnableEurekaClient
添加@RestController用作测试
@SpringBootApplication
//通过注解@EnableEurekaClient 表明自己是一个eurekaclient.
@EnableEurekaClient
@RestController
public class EurekaclientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaclientApplication.class, args);
}
@Value("${server.port}")
String port;
@RequestMapping("/hi")
public String home(@RequestParam String name) {
return "hi " + name + ",i am from port:" + port;
}
}
配置文件:application.yml
eureka:
client:
serviceUrl:
# 在哪个服务注册中心注册自己
defaultZone: http://localhost:7777/eureka/
server:
port: 8002
spring:
application:
#若没有配置serviceId,默认情况下spring.application.name相当于服务名
name: service-hi
三、测试
启动eureka-server,然后启动eureka-client,访问:http://localhost:7777/
可以看到向服务注册中心注册的服务。status为UP说明服务在线。
访问:http://localhost:8002/hi?name=mistra
Eureka Client在默认情况下会每隔30秒发送一次心跳来进行服务续约,告知Eureka Server该Eureka Client仍然可用。如果Eureka Server 90秒内没有收到心跳,Eureka Server会将该Eureka Client实例从注册列表中删除。
可以将服务器Eureka Server 集群部署,通过运行多个实例并要求它们相互注册,可以使Eureka更具弹性和可用性,每个服务器将注册服务的状态复制到其他服务器。也就是说一个Eureka Client只需要在一个注册中心注册,这个Client的信息就会被同步到其他的注册中心。
四、构建高可用的Eureka Server 集群
修改原来的eureka-server配置文件:
spring:
profiles:
active: instanceOne
application:
name: eureka-service
eureka:
client:
#不向注册中心注册自己
register-with-eureka: false
server:
enable-self-preservation: false
#是否从eureka服务器获取注册信息,这里不需要
fetch-registry: false
logging:
level:
com:
netflix:
eureka: OFF
discovery: OFF
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: ALWAYS
---
spring:
profiles: instanceOne
server:
port: 7777
eureka:
client:
service-url:
defaultZone: http://localhost:7778/eureka/
---
spring:
profiles: instanceTwo
server:
port: 7778
eureka:
client:
service-url:
defaultZone: http://localhost:7777/eureka/
记得关闭这个单实例配置
先启动spring.profiles.active.instanceOne下的eureka-server实例,然后修改active为instanceTwo,再启动一个eureka-server实例。让两个 Eureka 互相向对方注册。
最后启动eureka-client,并且只向7777端口的eureka-server注册中心注册。eureka-client还是默认的上面的那个配置。
查看注册中心:
端口7777:
端口7778:
eureka-client并没有向7778端口的注册中心注册自己,但是7778端口也有eureka-client的信息。两个注册中心 Eureka 相互注册了,所有注册到其中一个 Eureka 的服务实例信息会同步到另一个中。
把7777端口的eureka-server停了,eureka-client依然能够访问。