1. 程式人生 > >Spring Cloud 之 服務註冊與發現 Eureka元件,Eureka Server叢集

Spring Cloud 之 服務註冊與發現 Eureka元件,Eureka Server叢集

Eureka是Netflix公司開源的一個服務註冊與發現元件,類似的元件還有Zookeeper、Consul。
Eureka分為Eureka Server(服務註冊中心,每個服務都在這裡註冊資訊,提供服務名、IP、埠等資訊)和Eureka Client(客戶端) ,Eureka Client又可以分為服務提供者和服務消費者,譬如兩個服務都在註冊中心註冊了,同時服務消費者從註冊中心Eureka Server獲得一份在註冊中心註冊的所有服務註冊資訊,服務消費者就知道了所有服務提供者的IP,通過Http遠端排程來消費服務提供者的服務,他們相互之間呼叫彼此的介面了。這樣既是服務的提供者又是服務消費者。

一、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依然能夠訪問。

原始碼

這裡寫圖片描述