SpringCloudAlibaba之服務註冊與發現Nacos

1. 前言


Nacos 是阿里巴巴新的開源項目,可以快速實現動態服務發現、服務配置、服務元數據及流量管理。

本篇博客以實現服務註冊與發現爲主。

SpringCloud中也有一個同樣優秀的服務註冊與發現組件:Eureka,不過已經閉源了,這也是我爲什麼要學習 Nacos 的原因之一。

如果你也想了解 Eureka,那麼請前往:SpringCloud之服務註冊與發現Eureka+客戶端Feign。個人認爲兩者的搭建流程和使用思路很相似,

核心的相同之處:

  1. 引入依賴
  2. 配置註冊中心地址
  3. 添加註解

最大的不同之處:

  1. 服務端的搭建方式
  • Eureka Server 是自己手動搭建的
  • Nacos Server 需要通過源碼構建或者直接下載的方式搭建

再來說說 Nacos Server 一些其他的重要信息

部署方式: 三種部署模式,分別對應不同的使用場景

  1. 單機模式:方便本地測試用
  2. 集羣模式:適用於生產環境
  3. 多集羣模式:用於多數據中心

啓動方式: 兩種啓動方式,分別對應上面部署方式中的單機模式集羣模式

  1. Linux / Unix / Mac 系統中單機模式啓動需要添加 -m standalone 參數;反之,如果不加 -m standalone 參數則表示是集羣模式啓動。完整命令:sh startup.sh -m standalone
  2. Windows 系統中目前只支持單機模式啓動,直接雙擊啓動腳本文件。或完整命令:cmd startup.cmd

數據源: 兩種數據源,分別可以在配置文件中指定

  1. Derby:內嵌在應用中的數據庫(目前默認的數據源)
  2. MySQL:免費開源的關係型數據庫(版本需要 5.6.5+)

Nacos Server 的版本選擇: 目前官網推薦的穩定版本爲 1.2.1


2. 源碼


GitHub地址:https://github.com/intomylife/SpringCloud


3. 環境


  • JDK 1.8 +
  • Maven 3.2.x +
  • SpringBoot 2.0.6.RELEASE
  • SpringCloud Finchley.SR2
  • SpringCloudAlibaba 2.0.2.RELEASE

4. 開發工具


  • IntelliJ IDEA

5. 正文


5.1 commons 工程

5.1.1 commons 工程 - 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<!-- 三座標 -->
	<groupId>com.zwc</groupId>
	<artifactId>discovery-commons</artifactId>
	<version>1.0.0</version>

	<!-- 工程名稱和描述 -->
	<name>discovery-commons</name>
	<description>公用工程</description>

	<!-- 打包方式 -->
	<packaging>jar</packaging>

	<!-- 在 properties 下聲明相應的版本信息,然後在 dependency 下引用的時候用 ${} 就可以引入該版本 jar 包了 -->
	<properties>
		<!-- 編碼 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<!-- jdk -->
		<java.version>1.8</java.version>

		<!-- SpringBoot -->
		<platform-bom.version>Cairo-SR3</platform-bom.version>
		<!-- SpringCloud -->
		<spring-cloud-dependencies.version>Finchley.SR2</spring-cloud-dependencies.version>
		<!-- SpringCloudAlibaba -->
		<spring-cloud-alibaba-dependencies.version>2.0.2.RELEASE</spring-cloud-alibaba-dependencies.version>
	</properties>

	<!-- 加入依賴 -->
	<dependencies>
		<!-- springboot 起步依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
			<!-- 排除依賴 -->
			<exclusions>
				<exclusion>
					<groupId>ch.qos.logback</groupId>
					<artifactId>*</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.apache.logging.log4j</groupId>
					<artifactId>*</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- springboot web 依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<!-- 排除依賴 -->
			<exclusions>
				<exclusion>
					<groupId>ch.qos.logback</groupId>
					<artifactId>*</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.apache.logging.log4j</groupId>
					<artifactId>*</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- log4j2 依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-log4j2</artifactId>
		</dependency>
	</dependencies>

	<!-- 依賴 jar 包版本管理的管理器 -->
	<!-- 如果 dependencies 裏的 dependency 自己沒有聲明 version 元素,那麼 maven 就此處來找版本聲明。 -->
	<!-- 如果有,就會繼承它;如果沒有就會報錯,告訴你沒有版本信息 -->
	<!-- 優先級:如果 dependencies 裏的 dependency 已經聲明瞭版本信息,就不會生效此處的版本信息了 -->
	<dependencyManagement>
		<dependencies>
			<!-- SpringBoot -->
			<dependency>
				<groupId>io.spring.platform</groupId>
				<artifactId>platform-bom</artifactId>
				<version>${platform-bom.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<!-- SpringCloud -->
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud-dependencies.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<!-- SpringCloudAlibaba -->
			<dependency>
				<groupId>com.alibaba.cloud</groupId>
				<artifactId>spring-cloud-alibaba-dependencies</artifactId>
				<version>${spring-cloud-alibaba-dependencies.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>
  • 引入一些共用依賴

5.1.2 commons 工程 - 項目結構

springcloudalibaba-nacos-discovery/discovery-commons/
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── zwc
        │           └── core
        └── resources
            └── application.properties

5.2 service 工程

此工程下有五個模塊:

應用名稱 端口 描述
discovery-flyway-service 8082 輔助工程(自動創建數據庫和表)
discovery-master-service / 註冊中心(這裏的註冊中心工程其實就是 Nacos 的源碼,放入項目中只是爲了好找到)
discovery-provider-first-service 8090 提供者一號服務工程(對外提供服務)
discovery-provider-second-service 8091 提供者二號服務工程(對外提供服務)
discovery-consumer-service 8080 消費者服務工程(遠程調用服務)

詳細說明:

discovery-flyway-service: 前言中介紹了 Nacos Server 的數據源有兩種,這裏使用的是MySQL;而使用MySQL作爲數據源後需要建一些基礎表和插入一些基礎數據,這時就需要手動操作,然而爲了方便,我把這些“枯燥”的操作“簡化”了:啓動一下項目即可。可能唯一需要注意的就是,我本地的MySQL賬號密碼是root, 123456,如果和你的不一致,那麼就在 application.properties 配置文件中更改一下。

discovery-master-service: 此工程中僅僅就複製粘貼了 Nacos Server 的源碼,這裏放入到項目中爲了方便獲取是一方面原因;還有另一方面是因爲,需要在 Nacos Server 的配置文件中指定MySQL爲數據源,以及配置MySQL數據庫的連接信息,然而爲了方便,我已經在 Nacos Server 的源碼中改好了這些配置信息。可能唯一需要注意的就是,我本地的MySQL賬號密碼是root, 123456,如果和你的不一致,那麼就在 nacos-1.2.1/distribution/conf/application.properties 配置文件中的 25,26 行更改一下。nacos-1.2.1/distribution/conf/application.properties 作爲源碼構建後的默認配置文件,所以這裏先在源碼中修改對應的配置信息,從而方便配合在後面使用腳本來快速啓動 Nacos Server 服務。

discovery-provider-first-service: 作爲提供者,對外提供一個服務,服務的具體內容就是輸出一句話和當前服務的端口號。注意兩個提供者的應用名稱(spring.application.name)完全一致。

discovery-provider-second-service: 作爲提供者,對外提供一個服務,服務的具體內容就是輸出一句話和當前服務的端口號。注意兩個提供者的應用名稱(spring.application.name)完全一致。

discovery-consumer-service: 作爲消費者,來遠程調用服務,也就是調用上面的兩個提供者提供的服務。


其他補充說明:


5.2.1 discovery-flyway-service

5.2.1.1 discovery-flyway-service - 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 繼承父 -->
    <parent>
        <groupId>com.zwc</groupId>
        <artifactId>discovery-service</artifactId>
        <version>1.0.0</version>
    </parent>

    <!-- 三座標 -->
    <groupId>com.zwc</groupId>
    <artifactId>discovery-flyway-service</artifactId>
    <version>1.0.0</version>

    <!-- 工程名稱描述 -->
    <name>discovery-flyway-service</name>
    <description>輔助工程(自動創建數據庫和表)</description>

    <!-- 打包方式 -->
    <packaging>jar</packaging>

    <!-- 在 properties 下聲明相應的版本信息,然後在 dependency 下引用的時候用 ${} 就可以引入該版本 jar 包了 -->
    <properties>
        <!-- ali 連接池 -->
        <druid.version>1.1.9</druid.version>
    </properties>

    <!-- 加入依賴 -->
    <dependencies>
        <!-- 數據庫訪問依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- mysql 依賴 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- ali 連接池依賴 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- 數據庫版本管理 依賴 -->
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>
    </dependencies>

    <!-- 插件依賴 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • 此工程的作用和目的就是爲了自動創建數據庫和表,所以引入數據庫flyway相關依賴

5.2.1.2 discovery-flyway-service - application.properties 配置文件

# 端口
server.port=8082


# 數據源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/nacos_config?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=PRC&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456


## flyway    注:可以完全不用配置
### sql 腳本的位置,默認爲 classpath:db/migration。可手動指定
#spring.flyway.locations=classpath:db/migration
###  指定數據源,如果沒有指定的話,將使用配置的主數據源
#spring.flyway.url=jdbc:mysql://127.0.0.1:3306/nacos_config?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=PRC&useSSL=false
### Flyway 管理的 Schema 列表,區分大小寫。默認連接對應的默認 Schema
### 如果這裏明確指定了庫名,那麼在 spring.flyway.url 連接中指定的庫名將無效
#spring.flyway.schemas=nacos_config
### 用戶名
#spring.flyway.user=root
### 密碼
#spring.flyway.password=123456
### 開啓,默認開啓
#spring.flyway.enabled=true
  • 配置了連接數據庫的基本信息,如果賬號密碼與你的不一致記得修改一下
  • 由於flyway默認會取數據源的配置信息,所以這裏關於flyway的配置全部註釋,主要爲了如果是使用我的源代碼測試,數據源的信息可以少改一個地方,我的本地MySQL密碼是 123456,大家可能和我不一樣

5.2.1.3 discovery-flyway-service - 自動創建數據庫

package com.zwc.flyway.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @ClassName InitDatabaseConfig
 * @Desc TODO   自動創建數據庫
 * @Date 2020/6/21 8:38 PM
 * @Version 1.0
 */
@Configuration
public class InitDatabaseConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(InitDatabaseConfig.class);

    /**
     * 讀取配置文件中數據庫的連接信息
     */
    /**
     * 驅動名稱
     */
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    /**
     * 地址
     */
    @Value("${spring.datasource.url}")
    private String url;
    /**
     * 用戶名
     */
    @Value("${spring.datasource.username}")
    private String username;
    /**
     * 密碼
     */
    @Value("${spring.datasource.password}")
    private String password;


    /*
      * @ClassName InitDatabaseConfig
      * @Desc TODO  創建數據庫
      * @Date 2020/6/22 8:58 AM
      * @Version 1.0
     */
    @Bean(name = "dataSource")
    public DataSource dataSource() {
        LOGGER.info("==================================== InitDatabaseConfig -> dataSource -> 開始創建數據庫 ====================================");
        // 數據庫連接對象
        Connection connection = null;
        Statement statement = null;
        try {

            // 如果嘗試去連接不存在的數據庫會報錯,所以這裏連接的時候不帶數據庫名稱
            String connectionUrl = url.replace(("/" + (url.substring(0, url.indexOf("?"))).substring(((url.substring(0, url.indexOf("?"))).lastIndexOf("/")) + 1)), "");
            // 從連接地址中截取出數據庫名稱
            String databaseName = (url.substring(0, url.indexOf("?"))).substring(((url.substring(0, url.indexOf("?"))).lastIndexOf("/")) + 1);

            // 設置驅動
            Class.forName(driverClassName);
            // 連接數據庫
            connection = DriverManager.getConnection(connectionUrl, username, password);
            statement = connection.createStatement();

            // 創建數據庫
            statement.executeUpdate("create database if not exists `" + databaseName + "` default character set utf8mb4 COLLATE utf8mb4_general_ci");

        }catch (Exception e) {
            e.printStackTrace();
            LOGGER.info("==================================== InitDatabaseConfig -> dataSource -> 創建數據庫出錯:" + e.getMessage() + " ====================================");
        }finally {
            try {
                // 關閉連接
                statement.close();
                connection.close();
            }catch (SQLException e) {
                LOGGER.info("==================================== InitDatabaseConfig -> dataSource -> 關閉數據庫出錯:" + e.getMessage() + " ====================================");
            }
            LOGGER.info("==================================== InitDatabaseConfig -> dataSource -> 創建數據庫結束 ====================================");
        }

        // 創建數據源
        DruidDataSource druidDataSource = new DruidDataSource();
        // 設置數據源
        druidDataSource.setDriverClassName(driverClassName);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        // 返回數據源
        return druidDataSource;
    }

}
  • 使用@Configuration標註自定義配置類,在應用上下文加載時初始化

5.2.1.4 discovery-flyway-service - 自動新建數據表

由於引入了flyway-core依賴,所以只需要把初始化 sql 放在 flyway 默認會去讀取的db/migration目錄中,就可以了。具體內容可在源碼中查看,就不粘貼出來佔篇幅了。

5.2.1.5 discovery-flyway-service - 啓動項目

  1. 確認並修改好數據庫的連接信息後,啓動項目;發現項目啓動後就自動停止了,只要不報錯,這裏就是正常的,控制檯會打印如下日誌信息:
2020-07-04 18:35:34.120  INFO 2036 --- [           main] c.zwc.flyway.config.InitDatabaseConfig   : ==================================== InitDatabaseConfig -> dataSource -> 開始創建數據庫 ====================================
2020-07-04 18:35:34.347  INFO 2036 --- [           main] c.zwc.flyway.config.InitDatabaseConfig   : ==================================== InitDatabaseConfig -> dataSource -> 創建數據庫結束 ====================================
  1. 這時到MySQL圖形化連接工具中刷新本地庫,發現多了一個nacos_config數據庫,打開數據庫,可以看到一些基礎表已經被自動創建出來了
  2. 那麼,discovery-flyway-service 工程的作用就到此結束了

5.2.2 discovery-master-service

此工程中只有 Nacos Server 的源碼,就沒有太多搭建上的說明,唯一需要注意的就是上面提到過的數據庫連接賬號密碼,如果你的不是root, 123456,那麼就去修改一下。

但是此處需要着重說明的是如何快速構建這個源碼,當然,Nacos 官方文檔中已經寫的很詳細了,這裏就錦上添花一波,把一些命令再“封裝”一下,達到一行命令就能快速啓動 Nacos Server 服務的效果。

這裏分別爲本地快速開發測試以及日常使用兩種不同的場景編寫了腳本,放在了項目的 script 目錄中

springcloudalibaba-nacos-discovery/
├── discovery-commons
├── discovery-service
└── script
    ├── daily-use
    │   ├── nacos-start.sh
    │   └── nacos-stop.sh
    └── quick-start
        ├── nacos-install.bat
        ├── nacos-install.sh
        ├── nacos-start.bat
        ├── nacos-start.sh
        ├── nacos-stop.bat
        └── nacos-stop.sh

quick-start 目錄 - 快速開始:

  1. 使用IDEA打開 springcloudalibaba-nacos-discovery 項目
  2. 點擊IDEA底部的Terminal終端入口
  3. 進入到項目根目錄
MacBook-Pro:springcloudalibaba-nacos-discovery zouwencong$ pwd
/Users/zouwencong/JavaWork/my_spring_cloud/SpringCloud/springcloudalibaba-nacos-discovery
MacBook-Pro:springcloudalibaba-nacos-discovery zouwencong$ ls -all
total 32
drwxr-xr-x   7 zouwencong  staff    224 Jun 25 21:57 .
drwxr-xr-x  18 zouwencong  staff    576 Jul  3 13:54 ..
-rw-r--r--@  1 zouwencong  staff  12292 Jul  2 09:47 .DS_Store
drwxr-xr-x  10 zouwencong  staff    320 Jul  4 18:58 .idea
drwxr-xr-x  11 zouwencong  staff    352 Jun 28 16:08 discovery-commons
drwxr-xr-x  14 zouwencong  staff    448 Jul  2 16:41 discovery-service
drwxr-xr-x   5 zouwencong  staff    160 Jun 22 17:51 script
MacBook-Pro:springcloudalibaba-nacos-discovery zouwencong$ 
  1. 如果是Mac用戶,先輸入命令chmod +x script/quick-start/nacos-install.sh,然後再輸入命令./script/quick-start/nacos-install.sh
  2. 如果是Windows用戶,輸入命令script\quick-start\nacos-install.bat
  3. 第一次構建時間會相對久一點,我自己這裏用了大概兩三分鐘的樣子,因爲要到Maven中去下載SpringCloudAlibaba的相關依賴
  4. 如果是Mac用戶,執行完對應命令後會有如下日誌(截取最後關鍵部分):
...省略部分...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 38.467 s
[INFO] Finished at: 2020-07-04T19:42:13+08:00
[INFO] Final Memory: 110M/1588M
[INFO] ------------------------------------------------------------------------
...省略部分...
nacos is starting with standalone
nacos is starting,you can check the /Users/zouwencong/Downloads/SpringCloud-master/springcloudalibaba-nacos-discovery/discovery-service/discovery-master-service/nacos-1.2.1/distribution/target/naco-server-1.2.1/nacos/logs/start.out
[INFO] ----------------------------- end --------------------------------------
  1. 如果是Windows用戶,執行完對應的命令後會有如下日誌(截取最後關鍵部分):
...省略部分...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:18 min
[INFO] Finished at: 2020-07-04T19:52:11+08:00
[INFO] ------------------------------------------------------------------------
...省略部分...
2020-07-04 19:52:22,620 INFO Nacos started successfully in stand alone mode.

2020-07-04 19:52:22,857 INFO Initializing Servlet 'dispatcherServlet'

2020-07-04 19:52:22,865 INFO Completed initialization in 7 ms
  1. 這樣 Nacos Server 就啓動成功了,訪問 Nacos Server 主頁面:http://localhost:8848/nacos
  2. 賬號密碼:nacos, nacos
  3. 這裏對應還有停止的腳本
  4. 如果是Mac用戶,先輸入命令chmod +x script/quick-start/nacos-stop.sh,然後再輸入命令./script/quick-start/nacos-stop.sh
  5. 如果是Windows用戶,發現當前Terminal框並沒有可輸入的地方了,所以這裏想停止的話就先點擊+ (New Session)按鈕,然後再輸入命令script\quick-start\nacos-stop.bat
  6. 那麼如果想再啓動,因爲這裏都構建過了,所以分別使用啓動的腳本
  7. 如果是Mac用戶,先輸入命令chmod +x script/quick-start/nacos-start.sh,然後再輸入命令./script/quick-start/nacos-start.sh
  8. 如果是Windows用戶,輸入命令script\quick-start\nacos-start.bat

daily-use 目錄 - 日常使用:

我們可能以後項目中經常會用到 Nacos Server 服務,就像RedisMySQL一樣,當做一個服務來啓動,那麼就先把剛剛編譯構建後的目錄(discovery-master-service/nacos-1.2.1/distribution/target/nacos-server-1.2.1/nacos)複製到本地。由於是作爲日常使用的服務,所以再來設置一下日誌目錄

  1. 打開剛剛複製目錄(discovery-master-service/nacos-1.2.1/distribution/target/nacos-server-1.2.1/nacos)下的 conf/application.properties 配置文件
  2. Ctrl + F 搜索server.tomcat.basedir
  3. 後面就可以指定存放日誌的目錄路徑

由於Windows中啓動 Nacos Server 不需要指定參數,所以在剛剛複製目錄(discovery-master-service/nacos-1.2.1/distribution/target/nacos-server-1.2.1/nacos)下的 bin 目錄中的 .bat 腳本可以直接雙擊使用;而Mac中爲了方便,這裏也寫了一個日常使用的腳本,如何使用

  1. 複製 springcloudalibaba-nacos-discovery 項目中的 script/daily-use/nacos-start.sh 腳本文件和 script/daily-use/nacos-stop.sh 腳本文件到桌面
  2. 賦值執行權限:chmod +x nacos-start.shchmod +x nacos-stop.sh
  3. 右鍵nacos-start.sh文件
  4. 打開方式->其他...
  5. 啓用:選擇所有應用程序
  6. 勾選始終以此方式打開
  7. 點擊實用工具
  8. 雙擊終端
  9. nacos-stop.sh 也同樣設置一遍
  10. 都設置好後,現在只需要雙擊即可啓動停止 Nacos Server 服務
  11. 當然,你具體會把構建後的目錄複製到哪我是不知道的,所以腳本中的具體目錄需要對應的修改一下
  12. nacos-start.sh -> 第 20 行
  13. nacos-stop.sh -> 第 8 行

5.2.3 discovery-provider-first-service

5.2.3.1 discovery-provider-first-service - 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 繼承父 -->
    <parent>
        <groupId>com.zwc</groupId>
        <artifactId>discovery-provider-first-service</artifactId>
        <version>1.0.0</version>
    </parent>

    <!-- 三座標 -->
    <groupId>com.zwc</groupId>
    <artifactId>discovery-provider-first-service-core</artifactId>
    <version>1.0.0</version>

    <!-- 工程名稱描述 -->
    <name>discovery-provider-first-service-core</name>
    <description>提供者一號服務工程 - 核心</description>

    <!-- 打包方式 -->
    <packaging>jar</packaging>

    <!-- 在 properties下聲明相應的版本信息,然後在dependency下引用的時候用 ${} 就可以引入該版本jar包了 -->
    <properties>

    </properties>

    <!-- 加入依賴 -->
    <dependencies>
        <!-- commons 工程依賴 -->
        <dependency>
            <groupId>com.zwc</groupId>
            <artifactId>discovery-commons</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!-- api 工程依賴 -->
        <dependency>
            <groupId>com.zwc</groupId>
            <artifactId>discovery-provider-first-service-api</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!-- 提供者消費者 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

    <!-- 插件依賴 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • 加入 spring-cloud-starter-alibaba-nacos-discovery 依賴,表示會向 Nacos Server 中註冊自己

5.2.3.2 discovery-provider-first-service - application.yml 配置文件

# 端口
server:
  port: 8090

spring:
  application:
    # 應用名稱
    name: say-hello
  cloud:
    nacos:
      discovery:
        # 註冊中心地址
        server-addr: 127.0.0.1:8848
        # 用戶名
        username: nacos
        # 密碼
        password: nacos
  • 注意此處配置註冊中心地址的端口爲 8848 也就是 Nacos Server 的服務端口
  • 有兩個提供者工程,只有此處的端口不一致,此處端口爲 8090,另一個端口爲 8091。就不再贅述
  • 兩個提供者工程作用是爲了達到負載均衡的效果
  • spring.application.name:應用名稱,被消費者調用時需要用到
  • 注意這裏還配置了 Nacos Server 的用戶名和密碼,那是因爲我在 discovery-master-service/nacos-1.2.1/distribution/conf/application.properties 配置文件中把 nacos.core.auth.enabled 設置爲了 true,其實默認是 false 關閉的;開啓後這裏必須指定有效的用戶名和密碼,否則會報錯

5.2.3.3 discovery-provider-first-service - controller 前端控制器

package com.zwc.first.api;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName SayHelloController
 * @Desc TODO   Say Hello
 * @Date 2019/5/15 15:28
 * @Version 1.0
 */
@RestController
public class SayHelloController {

    /*
     * @ClassName SayHelloController
     * @Desc TODO   讀取配置文件中的端口
     * @Date 2019/5/15 15:49
     * @Version 1.0
     */
    @Value("${server.port}")
    private String port;

    /*
     * @ClassName SayHelloController
     * @Desc TODO   Say Hello
     * @Date 2019/5/15 15:30
     * @Version 1.0
     */
    @RequestMapping("/hello")
    public String hello(){
        return "Hello Spring Cloud Alibaba!!! port:" + port;
    }

}
  • 提供一個服務:輸出 Hello 和端口

5.2.3.4 discovery-provider-first-service - 啓動類

package com.zwc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class DiscoveryProviderFirstServiceCoreApplication {

    public static void main(String[] args) {
        SpringApplication.run(DiscoveryProviderFirstServiceCoreApplication.class, args);
    }

}
  • 添加 @EnableDiscoveryClient 註解表示此服務要向註冊中心註冊自己

5.2.3.5 discovery-provider-first-service - 啓動項目

  1. 項目啓動成功後訪問 http://localhost:8090/hello 看到輸出內容Hello Spring Cloud Alibaba!!! port:8090
  2. 刷新 http://localhost:8848/nacos/#/serviceManagement(註冊中心)可以看到服務已經被註冊進來了
服務名 分組名稱 集羣數目 實例數 健康實例數 觸發保護閾值 操作
say-hello DEFAULT_GROUP 1 1 1 false 詳情 | 示例代碼 | 刪除
  1. 同理,還有一個提供者工程只是端口不一致,也啓動起來
  2. 項目啓動成功後訪問 http://localhost:8091/hello 看到輸出內容Hello Spring Cloud Alibaba!!! port:8091
  3. 再次刷新 http://localhost:8848/nacos/#/serviceManagement(註冊中心)可以看到相同的服務有兩個提供者
服務名 分組名稱 集羣數目 實例數 健康實例數 觸發保護閾值 操作
say-hello DEFAULT_GROUP 1 2 2 false 詳情 | 示例代碼 | 刪除

5.2.4 discovery-consumer-service

5.2.4.1 discovery-consumer-service - 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 繼承父 -->
    <parent>
        <groupId>com.zwc</groupId>
        <artifactId>discovery-consumer-service</artifactId>
        <version>1.0.0</version>
    </parent>

    <!-- 三座標 -->
    <groupId>com.zwc</groupId>
    <artifactId>discovery-consumer-service-core</artifactId>
    <version>1.0.0</version>

    <!-- 工程名稱描述 -->
    <name>discovery-consumer-service-core</name>
    <description>消費者服務工程 - 核心</description>

    <!-- 打包方式 -->
    <packaging>jar</packaging>

    <!-- 在 properties下聲明相應的版本信息,然後在dependency下引用的時候用 ${} 就可以引入該版本jar包了 -->
    <properties>

    </properties>

    <!-- 加入依賴 -->
    <dependencies>
        <!-- commons 工程依賴 -->
        <dependency>
            <groupId>com.zwc</groupId>
            <artifactId>discovery-commons</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!-- api 工程依賴 -->
        <dependency>
            <groupId>com.zwc</groupId>
            <artifactId>discovery-consumer-service-api</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!-- 提供者消費者 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

    <!-- 插件依賴 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • 與提供者一致,加入 spring-cloud-starter-alibaba-nacos-discovery 依賴,表示會向 Nacos Server 中註冊自己
  • 並且還需要加入 Feign 的起步依賴 spring-cloud-starter-openfeign 表示自己會遠程調用其他服務

5.2.4.2 discovery-consumer-service - application.yml 配置文件

# 端口
server:
  port: 8080

spring:
  application:
    # 應用名稱
    name: service-feign
  cloud:
    nacos:
      discovery:
        # 註冊中心地址
        server-addr: 127.0.0.1:8848
        # 用戶名
        username: nacos
        # 密碼
        password: nacos

# 開啓斷路器
feign:
  hystrix:
    enabled: true
  • 注意此處配置註冊中心地址的端口爲 8848 也就是 Nacos Server 的服務端口
  • spring.application.name:應用名稱,被消費者調用時需要用到,它在消費的同時也可以被消費
  • 注意這裏還配置了 Nacos Server 的用戶名和密碼,那是因爲我在 discovery-master-service/nacos-1.2.1/distribution/conf/application.properties 配置文件中把 nacos.core.auth.enabled 設置爲了 true,其實默認是 false 關閉的;開啓後這裏必須指定有效的用戶名和密碼,否則會報錯
  • hystrix 熔斷功能需要主動開啓才能生效

5.2.4.3 discovery-consumer-service - 服務調用

package com.zwc.consumer.feign;

import com.zwc.consumer.feign.fallback.FeignApiFallBack;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @ClassName FeignApi
 * @Desc TODO   使用 Feign 調用 Api - 接口
 * @Date 2019/5/15 16:11
 * @Version 1.0
 */
@FeignClient(value = "say-hello", fallback = FeignApiFallBack.class)
public interface FeignApi {

    /*
     * @ClassName FeignApi
     * @Desc TODO   調用遠程 hello() 方法
     * @Date 2019/5/15 16:17
     * @Version 1.0
     */
    @RequestMapping("/hello")
    String hello();

}
  • 通過 @FeignClient 註解中 value = “say-hello” 來指定調用哪個服務
  • say-hello 就是提供者的 spring.application.name:應用名稱
  • 通過 @FeignClient 註解中 fallback = FeignApiFallBack.class 來指定熔斷時調用的方法
  • FeignApiFallBack 就是此接口(FeignApi)的實現類,對應的實現方法就是熔斷時調用的方法
  • String hello();:可以發現,此方法就是提供者 SayHelloController 中的方法,只不過這裏要定義成接口
  • 注意要與提供者具有相同返回值,相同方法名以及相同參數

5.2.4.4 discovery-consumer-service - Fallback(FeignApiFallBack)

package com.zwc.consumer.feign.fallback;

import com.zwc.consumer.feign.FeignApi;
import org.springframework.stereotype.Component;

/*
 * @ClassName FeignApi
 * @Desc TODO   fallback
 * @Date 2019/5/20 23:21
 * @Version 1.0
 */
@Component
public class FeignApiFallBack implements FeignApi {

    /*
     * @ClassName FeignApiFallBack
     * @Desc TODO   調用遠程 hello() 方法失敗時執行
     * @Date 2019/5/20 23:31
     * @Version 1.0
     */
    @Override
    public String hello() {
        return "Oh! Call say-hello fail.";
    }

}
  • 使用 @Component 註解把此類交給 Spring 管理
  • 實現了 FeignApi 接口,提供熔斷時對應的方法

5.2.4.5 discovery-consumer-service - controller 前端控制器(消費服務)

package com.zwc.consumer.controller;

import com.zwc.consumer.feign.FeignApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName FeignController
 * @Desc TODO   使用 Feign 調用 Api - 前端控制器
 * @Date 2019/5/15 16:18
 * @Version 1.0
 */
@RestController
public class FeignController {

    @Autowired(required = false)
    private FeignApi feignApi;

    /*
     * @ClassName FeignController
     * @Desc TODO   調用遠程 hello() 方法
     * @Date 2019/5/15 16:20
     * @Version 1.0
     */
    @RequestMapping("/feign")
    public String feign(){
        return feignApi.hello();
    }

}
  • 使用 @Autowired 註解裝配 Bean,通過此 Bean 中的方法調用服務
  • 此類對外暴露接口,調用的實則是提供者的服務

5.2.4.6 discovery-consumer-service - 啓動類

package com.zwc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class DiscoveryConsumerServiceCoreApplication {

    public static void main(String[] args) {
        SpringApplication.run(DiscoveryConsumerServiceCoreApplication.class, args);
    }

}
  • 添加 @EnableDiscoveryClient 註解表示此服務要向註冊中心註冊自己
  • 添加 @EnableFeignClients 註解表示開啓 Feign 功能進行遠程調用

5.2.4.7 discovery-consumer-service - 啓動項目

  1. 項目啓動成功後多次訪問 http://localhost:8080/feign
  2. 可以發現輪流輸出Hello Spring Cloud Alibaba!!! port:8090Hello Spring Cloud Alibaba!!! port:8091
  3. 此時已經達到了負載均衡的效果
  4. 再次刷新 http://localhost:8848/nacos/#/serviceManagement(註冊中心)可以看到此時多了一個消費者
服務名 分組名稱 集羣數目 實例數 健康實例數 觸發保護閾值 操作
service-feign DEFAULT_GROUP 1 1 1 false 詳情 | 示例代碼 | 刪除
say-hello DEFAULT_GROUP 1 2 2 false 詳情 | 示例代碼 | 刪除

5.3 service 工程 - 項目結構

springcloudalibaba-nacos-discovery/discovery-service/
├── discovery-consumer-service
│   ├── discovery-consumer-service-api
│   ├── discovery-consumer-service-core
│   ├── mvnw
│   ├── mvnw.cmd
│   └── pom.xml
├── discovery-flyway-service
│   ├── mvnw
│   ├── mvnw.cmd
│   ├── pom.xml
│   └── src
├── discovery-master-service
│   ├── mvnw
│   ├── mvnw.cmd
│   ├── nacos-1.2.1
│   └── pom.xml
├── discovery-provider-first-service
│   ├── discovery-provider-first-service-api
│   ├── discovery-provider-first-service-core
│   ├── mvnw
│   ├── mvnw.cmd
│   └── pom.xml
├── discovery-provider-second-service
│   ├── discovery-provider-second-service-api
│   ├── discovery-provider-second-service-core
│   ├── mvnw
│   ├── mvnw.cmd
│   └── pom.xml
├── mvnw
├── mvnw.cmd
└── pom.xml

6. 把項目使用 IntelliJ IDEA 打開

  1. 把項目從 GitHub 中下載到你的本地
  2. 打開 IntelliJ IDEA
  3. 點擊 File -> Open
  4. 打開你下載到本地的項目目錄
  5. springcloudalibaba-nacos-discovery(選擇打開此工程)
  6. 如果是高版本的 IntelliJ IDEA,則在右下角會提示有一些工程可以導入,那麼選擇一鍵導入就可以了
  7. 如果是低版本的 IntelliJ IDEA,則手動來導入
  8. 點擊右側 Maven Projects 入口
  9. 點擊 + (Add Maven Projects)
  10. 分別選擇 discovery-commons 工程和 discovery-service 工程的 pom.xml 文件,點擊 Open 按鈕


希望能夠幫助到你

over




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章