搭建 Spring Cloud Eureka Server 高可用注册中心集群
什么是注册中心
Eureka Server 在微服务中承担的角色是服务注册中心,也是最最基础的核心设施之一。从“Eureka”单词的含义“我找到了!我发现了!”可以看出,其实 Eureka 就是用来实现服务注册、服务发现的工具,和 dubbo 这类的分布式服务治理框架类似。各种独立的微服务将自己注册到 Eureka Server,Eureka Client 则提供了服务发现的能力。
本文目的
Eureka的特点在于可以相互注册,形成高可用注册中心集群。这篇文章记录一下本地搭建两个 Eureka Server 注册中心,让他们互相注册自己到对方的服务中心,最后创建一个名为 hello-service
的微服务,将它们注册到注册中心。
开发环境
- IntelliJ IDEA 2018.1.6
- Maven-3.5.3
- JDK8
- spring cloud版本:Finchley.RELEASE
- spring-boot-starter版本:2.0.3.RELEASE
准备工作
由于是本地在同一台机器上模拟搭建两个注册中心,需要修改 HOSTS 文件,这里以 Win10 系统为例,HOSTS 文件的路径在 C:\Windows\System32\drivers\etc
。
在末尾追加内容如下,表示访问 eureka-server1 和 eureka-server2 时,等于访问 127.0.0.1:
127.0.0.1 eureka-server1
127.0.0.1 eureka-server2
第1步:搭建注册中心1
在IDEA创建工程,取名为 cat-spring-cloud-eureka-server-1
,通过Spring初始化工具,添加 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>me.zebe</groupId>
<artifactId>cat-spring-cloud-eureka-server-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>cat-spring-cloud-eureka-server-1</name>
<description>pring Cloud Eureka 注册中心1</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.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>
<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-server</artifactId>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml:
server:
port: 20001
eureka:
instance:
# eureka-server1 是一个别名,需要在 hosts 文件里面将其映射为 127.0.0.1
hostname: eureka-server1
client:
serviceUrl:
# 将自身反注册到eureka-server2,利用相互注册,形成高可用注册中心集群
defaultZone: http://eureka-server2:20002/eureka/
# 将当前服务注册中心本身也作为服务注册到别的服务注册中心(eureka-server2)
register-with-eureka: true
# 不将当前服务注册中心本身也作为服务注册到别的服务注册中心(如设为false,则 eureka-server2 中,unavailable-replicas 会包含此注册中心)
# register-with-eureka: false
应用启动器类:
package me.zebe.cat.spring.cloud.eureka.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* Spring Cloud Eureka 注册中心1
*
* @author Zebe
*/
@EnableEurekaServer
@SpringBootApplication
public class CatSpringCloudEurekaServer1Application {
/**
* 运行入口
* @param args 运行参数
*/
public static void main(String[] args) {
SpringApplication.run(CatSpringCloudEurekaServer1Application.class, args);
System.out.println("Spring Cloud Eureka 注册中心1 -> 已启动。");
}
}
运行该类,启动时会抛出异常,提示找不到 eureka-server2,这是因为 eureka-server2 我们没有启动,不用管它。
第2步:搭建注册中心2
第二个注册中心和第一个注册中心没有本质上的区别,只不过是换了运行端口和注册地址。将第二个工程取名为 cat-spring-cloud-eureka-server-2
。
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>me.zebe</groupId>
<artifactId>cat-spring-cloud-eureka-server-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>cat-spring-cloud-eureka-server-2</name>
<description>pring Cloud Eureka 注册中心2</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.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>
<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-server</artifactId>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml:
server:
port: 20002
eureka:
instance:
# eureka-server2 是一个别名,需要在 hosts 文件里面将其映射为 127.0.0.1
hostname: eureka-server2
client:
serviceUrl:
# 将自身反注册到eureka-server1,利用相互注册,形成高可用注册中心集群
defaultZone: http://eureka-server1:20001/eureka/
# 将当前服务注册中心本身也作为服务注册到别的服务注册中心(eureka-server1)
register-with-eureka: true
# 不将当前服务注册中心本身也作为服务注册到别的服务注册中心(如设为false,则 eureka-server1 中,unavailable-replicas 会包含此注册中心)
# register-with-eureka: false
应用启动器类:
package me.zebe.cat.spring.cloud.eureka.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* Spring Cloud Eureka 注册中心2
*
* @author Zebe
*/
@EnableEurekaServer
@SpringBootApplication
public class CatSpringCloudEurekaServer2Application {
/**
* 运行入口
* @param args 运行参数
*/
public static void main(String[] args) {
SpringApplication.run(CatSpringCloudEurekaServer2Application.class, args);
System.out.println("Spring Cloud Eureka 注册中心2 -> 已启动。");
}
}
运行该类,只要 hosts 文件里面按照配置里面修改好了,启动时就不会报异常了。
第3步:启动注册中心
先启动注册中心1,忽略报错信息,然后再启动注册中心2。分别访问 http://127.0.0.1:20001 和 http://127.0.0.1:20002 。
可以看到两个注册中心已经互相注册,配置文件的注释里面已经写清楚了如何观察。
注册中心1:
注册中心2:
第4步:制作快速启动脚本(非必需)
将这两个注册中心工程,分别用Maven打包成JAR文件,然后写好批处理文件,后面就可以一健启动了,比如我为这两个应用写了批处理文件,如下所示:
- 01 一健启动 Eureka 注册中心-1 运行在 20001.cmd
- 02 一健启动 Eureka 注册中心-2 运行在 20002.cmd
内容参考:
title EurekaServer1-20001
java -jar cat-spring-cloud-eureka-server-1-0.0.1-SNAPSHOT.jar
title EurekaServer2-20002
java -jar cat-spring-cloud-eureka-server-2-0.0.1-SNAPSHOT.jar
强烈建议写为批处理文件,因为如果要本地搭建为服务学习环境,注册中心是首先要启动的基础设施。
第5步:编写 HELLO-SERVICE 微服务
创建工程,取名为 cat-spring-cloud-hello-service
。该工程很简单,需要依赖于 eureka client 来实现服务发现,注意需要引用 starter-web 提供WEB访问功能。
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>me.zebe</groupId>
<artifactId>cat-spring-cloud-hello-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>cat-spring-cloud-hello-service</name>
<description>Spring Cloud Hello-Service 服务实现</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.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>
<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>
</dependency>
<!-- spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml:
server:
port: 8001
spring:
application:
name: hello-service
eureka:
client:
serviceUrl:
# 如果这里只配置一个服务注册中心 eureka-server1,那么当 eureka-server1 挂掉,服务便无法注册上去
# defaultZone: http://eureka-server1:20001/eureka/
# 因此,通常的做法是,将注册中心的地址写成多个(用逗号隔开时,不要有空格,不然可能会报解析错误)
defaultZone: http://eureka-server1:20001/eureka/,http://eureka-server1:20002/eureka/
# 将当前服务注册到eureka服务注册中心,这样消费者就可以发现服务
register-with-eureka: true
# 如果设置为false,则不会注册到服务中心
#register-with-eureka: false
应用启动器类:
package me.zebe.cat.spring.cloud.service.hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* Spring Cloud {Hello-Service} 服务提供者
*
* @author Zebe
*/
@EnableEurekaClient
@SpringBootApplication
public class CatSpringCloudEurekaHelloServiceApplication {
/**
* 运行入口
* @param args 运行参数
*/
public static void main(String[] args) {
SpringApplication.run(CatSpringCloudEurekaHelloServiceApplication.class, args);
System.out.println("Spring Cloud Eureka {Hello-Service} 服务提供者 -> 已启动。");
}
}
服务提供控制器类:
package me.zebe.cat.spring.cloud.service.hello;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* {Hello-Service} 服务提供者控制器
*
* @author Zebe
*/
@RestController
public class HelloServiceController {
@Value("${server.port}")
private int port;
/**
* Hello
* @return 返回字符串
*/
@GetMapping("/hello")
public String hello() {
// 返回值里面显示当前的端口号,这样可以用来测试单个服务节点挂掉之后的运行情况
return "{Hello} From " + port;
}
}
启动该服务,观察注册中心,可以看到服务注册成功。到此为止,一个简单的微服务注册例子就完成了。
服务运行截图:
推荐阅读
-
Spring cloud Eureka注册中心搭建的方法
-
Spring-Cloud Eureka注册中心实现高可用搭建
-
springcloud(二):spring cloud eureka 注册中心server 启动
-
我的Spring Cloud(二):Eureka Server注册中心
-
基于Spring Boot 2.0.2.RELEASE 的 Spring Cloud 速成指南 | 二. Spring Cloud 服务注册中心(Eureka Server)
-
Spring Cloud--搭建Eureka注册中心服务
-
Spring Cloud--实现Eureka的高可用(Eureka集群搭建)实例
-
高可用注册中心 ->Spring Cloud Eureka
-
【Spring Cloud】Eureka服务注册中心搭建
-
【Spring Cloud】Eureka服务注册中心搭建