搭建 Spring Cloud Eureka Server 高可用注册中心集群

版权声明:知识诚无价,分享价更高。 https://blog.csdn.net/u013955940/article/details/82692436

什么是注册中心

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:20001http://127.0.0.1:20002
可以看到两个注册中心已经互相注册,配置文件的注释里面已经写清楚了如何观察。

注册中心1
spring-cloud-eureka-server-1

注册中心2
spring-cloud-eureka-server-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-hello-service-1

spring-cloud-hello-service-2


本文首发于个人独立博客,文章链接:http://www.zebe.me/spring-cloud-eureka-server

猜你喜欢

转载自blog.csdn.net/u013955940/article/details/82692436