[SpringCloud教程]3. Eureka服務註冊中心整合

晴天天天藍發表於2021-04-07

新微服務專案多半採用Nacos作為服務註冊與發現中心,但是舊專案可能使用Eureka、zookeeper、Consul、Nacos作為服務註冊中心。
新專案建議使用Nacos作為服務註冊中心

根專案建立

  • 建立一個maven專案,刪除src目錄,然後編輯pom.xml檔案
    其中核心部分就是SpringCloud、SpringBoot、SpringCloudAlibaba的版本號
    • Spring Cloud Version: Spring Cloud Hoxton.SR8
    • Spring Cloud Alibaba Version: 2.2.5.RELEASE
    • Spring Boot Version: 2.3.2.RELEASE
<?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.spz.demo</groupId>
    <artifactId>spring-cloud-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <!-- <module>api-common</module>
        <module>ms-provider</module>
        <module>ms-consumer</module>
        <module>eureka-server</module> -->
    </modules>

    <!-- 統一管理jar包版本 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>

        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql.version>8.0.16</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.plus.version>3.3.2</mybatis.plus.version>
        <jackson-version>2.9.9</jackson-version>
    </properties>

    <dependencyManagement>
        <dependencies>

            <!-- Spring Boot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Spring Cloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Spring Cloud Alibaba -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis.plus.version}</version>
            </dependency>


            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>

        </dependencies>
    </dependencyManagement>
</project>

專案結構

  • eureka-server: Eureka服務端
  • ms-consumer: 服務消費者
  • ms-provider: 服務提供者
  • api-common: 公共模組
    f3f1de3d73b56dceb4105d400186c60a4e0033704f417bd713e0e935840ea480.png

Eureka 服務註冊中心 服務端(eureka-server)

首先需要在根pom.xml的modules標籤下加入該模組:

<modules>
    <module>api-common</module>
    <!-- 
    <module>ms-provider</module>
    <module>ms-consumer</module> -->
    <module>eureka-server</module>
</modules>

單節點 Eureka Server 節點搭建

  • 在根專案下建立eureka-server目錄,然後在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>
    <parent>
        <groupId>com.spz.demo</groupId>
        <artifactId>spring-cloud-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>eureka-server</artifactId>
    <packaging>jar</packaging>

    <description>Eureka註冊中心</description>

    <dependencies>

        <!-- Eureka Server-->
        <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-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>com.spz.demo</groupId>
            <artifactId>api-common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

</project>

  • 建立src/main/java和src/main/resources目錄
  • 在src/main/java目錄下建立包com.spz.demo.scloud.register.eureka

5f716b2f5c0416ade2833ba23ed253620699bdad6629def64d8f52fc9f428dbf.png

  • 在eureka包下建立啟動類 RegisterServerEureka.java
package com.spz.demo.scloud.register.eureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class RegisterServerEureka {
    public static void main(String[] args) {
        SpringApplication.run(RegisterServerEureka.class, args);
    }
}
  • 在src/main/resources目錄下建立application.properties檔案
    • eureka.client.service-url.defaultZone: 這裡只需要配置除自己以外的其他服務端節點,因為是將本節點註冊給其他註冊中心,來實現互相註冊的高可用叢集
server.port=6001
spring.application.name=@project.artifactId@

# Eureka 配置
# Eureka Server 例項 hostname
eureka.instance.hostname=eureka6001
# 服務端不需要註冊自己
eureka.client.register-with-eureka=false
# 服務端不需要檢索服務
eureka.client.fetch-registry=false
# Eureka Server 向其他服務端註冊自己,實現Eureka的高可用叢集
eureka.client.service-url.defaultZone=http://eureka6002:6002/eureka,http://eureka6003:6003/eureka
# 關閉自我保護機制,保證不可用服務被及時踢除,建議生產環境保持預設
#eureka.server.enable-self-preservation=false
#eureka.server.eviction-interval-timer-in-ms=2000

高可用 Eureka Server 叢集實現

eureka 服務端例項實現高可用叢集的方法是多個Eureka Server節點互相註冊。比如A、B、C三個節點,A把自己作為Eureka客戶端註冊到B、C節點;B把自己註冊到A、C節點;C把自己註冊到A、B節點。這樣三個節點互相具備其他服務端節點的資訊,客戶端列表資料也相當於儲存了三分,這時候某個服務端節點失效,並不會造成客戶端資訊缺失,由此實現了高可用叢集。下面介紹高可用叢集實現方法:

  • 配置Eureka 服務端節點所屬伺服器的hosts,這裡採用本地部署多個Eureka服務端的方案代替
    假設三個Eureka服務端節點的hostname分別為eureka6001、eureka6002、eureka6003。(注意:不配置hosts會導致Eureka叢集無法進行備份,因為必須保證每個節點的hostname不同)
127.0.0.1  eureka6001
127.0.0.1  eureka6002
127.0.0.1  eureka6003
  • IDEA方式啟動 - eureka6001節點配置
    70b5948212d5e231ae147f03e55870bcc2729ab12d3f1b76857543c3e121e650.png
    vm options:
-Dserver.port=6001
-Deureka.instance.hostname=eureka6001
-Deureka.client.service-url.defaultZone=http://eureka6002:6002/eureka,http://eureka6003:6003/eureka
  • IDEA方式啟動 - eureka6002節點配置

c1c5770b3dfa3fea48b56820e6116bf38dea647650ec2b53c80486fd3ddf3376.png
vm options:

-Dserver.port=6002
-Deureka.instance.hostname=eureka6002
-Deureka.client.service-url.defaultZone=http://eureka6001:6001/eureka,http://eureka6003:6003/eureka
  • IDEA方式啟動 - eureka6003節點配置

5ed09e468c0b40db2d5e6d5dc03784121fd6b695203d12e7d665740f021454df.png
vm options:

-Dserver.port=6003
-Deureka.instance.hostname=eureka6003
-Deureka.client.service-url.defaultZone=http://eureka6002:6002/eureka,http://eureka6001:6001/eureka

bd6dc0716faefb1e3a12f795c362b4bc243629d2f61f6d7392e6f53dfe8e55ae.png
如圖eureka6001節點的DS Replicas出現了另外兩個相鄰節點,說明這三個節點組成了一個叢集,這時候訪問另外兩個節點的管理頁,也能同樣看到DS Replicas裡出現其他兩個節點。另外,當有客戶端註冊進服務端時,三個服務端節點裡應該有同一份的客戶端列表資訊。至此Eureka叢集搭建成功。

服務提供者叢集(ms-provider)

首先需要在根pom.xml的modules標籤下加入該模組:

<modules>
    <module>api-common</module>
    <module>ms-provider</module>
    <!-- <module>ms-consumer</module> -->
    <module>eureka-server</module>
</modules>

單節點ms-provider搭建

  • 在根專案下建立ms-provider目錄,然後在ms-provider目錄下建立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>
    <parent>
        <groupId>com.spz.demo</groupId>
        <artifactId>spring-cloud-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>ms-provider</artifactId>
    <packaging>jar</packaging>

    <description>服務提供者模組</description>

    <dependencies>

        <!-- sleuth zipkin 服務追蹤 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>

        <!-- eureka client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>com.spz.demo</groupId>
            <artifactId>api-common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

</project>

  • 建立src/main/java和src/main/resources目錄
  • 在src/main/resources下建立application.properties檔案
    • eureka.client.service-url.defaultZone: 這裡配置的是Eureka服務端叢集,啟動後該服務將把自己註冊進Eureka註冊中心叢集
    • spring.application.name: 將作為服務名註冊進Eureka註冊中心(使用RestTemplate+負載均衡來呼叫Eureka服務時,服務名不能有下劃線)
server.port=8001
spring.application.name=MS-PROVIDER

# 服務追蹤
#spring.zipkin.base-url=http://localhost:9411
#取樣率值介於 0 到 1 之間,1 則表示全部採集
#spring.sleuth.sampler.probability=1

# eureka 配置
# 是否將自己註冊進 EurekaServer 預設為true
eureka.client.register-with-eureka=true
# 是否從 EurekaServer 抓取已有的註冊資訊,預設為true。單節點無所謂,叢集必須設定為true才能配合ribbon使用負載均衡
eureka.client.fetchRegistry=true
eureka.client.service-url.defaultZone=http://eureka6001:6001/eureka,http://eureka6002:6002/eureka,http://eureka6003:6003/eureka
# 例項ID
eureka.instance.instance-id=${spring.application.name}-${server.port}
# 訪問路徑可以顯示IP地址
eureka.instance.prefer-ip-address=true
# Eureka客戶端向服務端傳送心跳的時間間隔,單位為秒(預設是30秒)
eureka.instance.lease-renewal-interval-in-seconds=1
# Eureka服務端在收到最後一次心跳後等待時間上限,單位為秒(預設是90秒),超時將剔除服務
eureka.instance.lease-expiration-duration-in-seconds=10


  • 在src/main/java目錄下建立包com.spz.demo.scloud.provider
  • 在provider包下建立其他包、類和啟動類

9bb8301caa3cdda53fc3dac668bdce10d7de139e6ce6b044eabbfa3567821cc1.png

  • IndexController.java
    package com.spz.demo.scloud.provider.controller;
    
    import com.spz.demo.scloud.common.core.bean.RestBean;
    import com.spz.demo.scloud.common.service.AppService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("")
    public class IndexController {
    
        @Autowired
        private AppService appService;
    
        /**
        * 獲取專案資訊
        * @return
        */
        @RequestMapping("/projectInfo")
        public RestBean projectInfo(){
            String msg = appService.instanceNameAndPort();
            return RestBean.ok(msg);
        }
    
    }
    
    
  • AppServiceImpl.java
    注意該該類實現的AppService.java介面存放於api-common包,該包程式碼請在此處檢視(https://gitee.com/spzmmd/spring-cloud-demo)
    package com.spz.demo.scloud.provider.service;
    
    import com.spz.demo.scloud.common.service.AppService;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    /**
    * App Service 介面實現類
    */
    @Service
    public class AppServiceImpl implements AppService {
    
        /**
        * 專案埠
        */
        @Value("${server.port}")
        private Integer projectServerPort;
    
        /**
        * 專案名稱
        */
        @Value("${spring.application.name}")
        private String projectApplicationName;
    
        @Override
        public String instanceNameAndPort(){
            return projectApplicationName + ":" + projectServerPort;
        }
    
    }
    
    
  • ProviderApp.java 啟動類
    package com.spz.demo.scloud.provider;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @EnableEurekaClient
    @EnableDiscoveryClient
    @SpringBootApplication
    public class ProviderApp {
        public static void main(String[] args) {
            SpringApplication.run(ProviderApp.class, args);
        }
    }
    

叢集實現

客戶端服務(這裡是本機,所以只需要配置一次,如果是不同伺服器則需要配置)也需要配置hosts,不然無法訪問Eureka註冊中心叢集

127.0.0.1  eureka6001
127.0.0.1  eureka6002
127.0.0.1  eureka6003
  • IDEA方式啟動 - 8001節點

bc00d06700ccf9047af2b7766374eed137c67959e950e025b9f37c1fbc88f90b.png
vm options:

-Dserver.port=8001
-Deureka.client.service-url.defaultZone=http://eureka6001:6001/eureka,http://eureka6002:6002/eureka,http://eureka6003:6003/eureka
  • IDEA方式啟動 - 8002節點

d42f34a85318f09a6896499be1d5b72389fc12c84baef9f0152d363827a6f8b5.png
vm options:

-Dserver.port=8002
-Deureka.client.service-url.defaultZone=http://eureka6001:6001/eureka,http://eureka6002:6002/eureka,http://eureka6003:6003/eureka
  • IDEA方式啟動
    啟動ProviderApp8001、ProviderApp8002即可,啟動後分別訪問三個註冊中心的管理端:

  • 訪問三個註冊中心管理端,應該均可以看到這裡有相同的客戶端資訊

    • MS-PROVIDER-8001: 這裡是在application.properties裡的"eureka.instance.instance-id"配置的,也即是例項ID
    • MS-PROVIDER: 這裡是在application.properties裡的"spring.application.name"配置的,也即是服務名(使用RestTemplate+負載均衡來呼叫Eureka服務時,服務名不能有下劃線)

69d82e13a4970b5bcf90c5e759a3eb4db24012c123d4dd6fa1adccebe3035455.png
服務提供者叢集搭建完成

服務消費者例項(ms-consumer)

首先需要在根pom.xml的modules標籤下加入該模組:

<modules>
    <module>api-common</module>
    <module>ms-provider</module>
    <module>ms-consumer</module>
    <module>eureka-server</module>
</modules>

單節點ms-consumer搭建

  • 在根專案下建立ms-consumer目錄,然後在ms-consumer目錄下建立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>
    <parent>
        <groupId>com.spz.demo</groupId>
        <artifactId>spring-cloud-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>ms-consumer</artifactId>
    <packaging>jar</packaging>

    <description>消費者模組</description>

    <dependencies>

        <!-- sleuth zipkin 服務追蹤 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>

        <!-- eureka client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>com.spz.demo</groupId>
            <artifactId>api-common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

</project>

  • 建立src/main/java和src/main/resources目錄
  • 在src/main/resources下建立application.properties檔案
    • eureka.client.service-url.defaultZone: 這裡配置的是Eureka服務端叢集,啟動後該服務將把自己註冊進Eureka註冊中心叢集
    • spring.application.name: 將作為服務名註冊進Eureka註冊中心
server.port=7001
spring.application.name=MS-CONSUMER

# 服務追蹤
#spring.zipkin.base-url=http://localhost:9411
#取樣率值介於 0 到 1 之間,1 則表示全部採集
#spring.sleuth.sampler.probability=1

# Eureka 註冊中心配置
# 是否將自己註冊進 Eureka Server 預設為true
eureka.client.register-with-eureka=true
# 例項ID
eureka.instance.instance-id=${spring.application.name}-${server.port}
# 訪問路徑可以顯示IP地址
eureka.instance.prefer-ip-address=true
# 是否從 Eureka Server 抓取已有的註冊資訊,預設為true 單節點無所謂,叢集必須設定為true才能配合ribbon使用負載均衡
eureka.client.fetchRegistry=true
# Eureka Server 叢集
eureka.client.service-url.defaultZone=http://eureka6001:6001/eureka,http://eureka6002:6002/eureka,http://eureka6003:6003/eureka
  • 在src/main/java目錄下建立包com.spz.demo.scloud.consumer
  • 在consumer包下建立其他包、類和啟動類

c31abf28bd34089a8d785084e7f29fa75a3a825df99ed03249a99338b2f38824.png

  • RestTemplateConfig.java
    • RestTemplate用於消費者遠端訪問服務提供者提供的介面
    • 注意需要@LoadBalanced註解,否則RestTemplate無法從服務提供者叢集裡獲取例項
    package com.spz.demo.scloud.consumer.config;
    
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    /**
    * RestTemplate 配置
    */
    @Configuration
    public class RestTemplateConfig {
        @Bean
        @LoadBalanced
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    }
    
  • DiscoveryEurekaController.java
    用於測試Eureka註冊中心
    package com.spz.demo.scloud.consumer.controller;
    
    import com.spz.demo.scloud.common.core.bean.RestBean;
    import com.spz.demo.scloud.common.service.AppService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import javax.annotation.Resource;
    import java.net.URI;
    import java.util.List;
    
    /**
    * 註冊中心 - Eureka - 測試介面
    */
    @Slf4j
    @RestController
    @RequestMapping("/discovery/eureka")
    public class DiscoveryEurekaController {
    
        @Autowired
        private DiscoveryClient discoveryClient;
    
        @Autowired
        private RestTemplate restTemplate;
    
        /**
        * 服務遠端呼叫測試 - 使用 RestTemplate
        * @see AppService#instanceNameAndPort()
        * @return
        */
        @RequestMapping("/appService/projectInfo")
        public RestBean appServiceProjectInfo(){
            RestBean restBean = restTemplate.postForObject("http://MS-PROVIDER/projectInfo",null, RestBean.class);
            return restBean;
        }
    
        /**
        * 獲取已在 Eureka Server 註冊的服務名稱列表
        * 注意不是服務名下的例項名稱列表,是 Eureka的Application名稱列表
        * @return
        */
        @RequestMapping("/services")
        public RestBean services(){
            List<String> services = discoveryClient.getServices();
            return RestBean.ok(services);
        }
    
        /**
        * 根據名稱獲取例項列表
        * 1. 如多個服務註冊到Eureka服務端,他們的名稱均為MS-PROVIDER,則使用MS-PROVIDER可查詢出所有已註冊例項
        * 2. 獲取到ServiceInstance物件裡包含例項的ServiceId、host、port、uri等
        * @param name eg. MS-PROVIDER
        * @return
        */
        @GetMapping("/instances/{name}")
        public RestBean instancesByName(@PathVariable(name = "name", required = true) String name){
            List<ServiceInstance> instances = discoveryClient.getInstances(name);
            return RestBean.ok(instances);
        }
    }
    
  • ConsumerApp.java 啟動類
    package com.spz.demo.scloud.consumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @EnableEurekaClient
    @EnableDiscoveryClient
    @SpringBootApplication
    public class ConsumerApp {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApp.class, args);
        }
    }
    
  • IDEA方式啟動 - 7001節點

b8ad5c365ee75fb59971ffccf250ee1c47f48b068668965a8e2d5aa6e649281a.png
vm options:

-Dserver.port=7001
-Deureka.client.service-url.defaultZone=http://eureka6001:6001/eureka,http://eureka6002:6002/eureka,http://eureka6003:6003/eureka
  • 啟動後,不斷訪問如下地址
http://localhost:7001/discovery/eureka/appService/projectInfo

可以發現返回的埠號會在8001和8002之間交替變化,說明服務提供者註冊的兩個例項均可以訪問

{
"code": 2000,
"message": "MS-PROVIDER:8001",
"data": null
}

{
"code": 2000,
"message": "MS-PROVIDER:8002",
"data": null
}

叢集實現

於服務提供者叢集實現方式相似,這裡不再贅述

參考

交流&聯絡

  • QQ群
    歡迎加入Java交流群(qq群號: 776241689 )

  • 公眾號
    PS:小到Java後端技術、計算機基礎知識,大到微服務、Service Mesh、大資料等,都是本人研究的方向。我將定期在公眾號中分享技術乾貨,希望以我一己之力,拋磚引玉,幫助朋友們提升技術能力,共同進步!
    在這裡插入圖片描述

  • 部落格

原創不易,轉載請在開頭著名文章來源和作者。如果我的文章對您有幫助,請點贊/收藏/關注鼓勵支援一下吧❤❤❤❤❤❤

相關文章