nacos使用-服務注冊中心和配置中心


本例子基於 spring boot + spring cloud alibaba + spring cloud, nacos作為服務注冊中心和配置中心。

簡介

Nacos 是Spring Cloud Alibaba 的一個組件。致力於發現、配置和管理微服務。

Nacos名字:前四個字母分別為 Naming 和 Configuration 的前兩個字母,最后的 s 為 Service。

下載啟動

版本選擇

如果是使用spring boot + spring cloud alibaba + spring cloud全家桶。那么版本選擇一定要按照官網匹配,否則會因jar包沖突導致項目啟動失敗。

我們可以去spring cloud alibaba的版本說明查看

版本說明

在此文中,我選擇的版本為spring boot - 2.2.5.RELEASE, spring cloud alibaba - 2.2.1.RELEASE, spring cloud - Hoxton.SR3

下載

nacos下載地址 https://github.com/alibaba/nacos/releases

根據上面的版本說明,我這里選擇1.2.1

啟動

下載解壓后,進入bin目錄

nacos的bin目錄

可以看到啟動命令。其中cmd是window系統使用,sh是linux系統使用。

我們本地測試使用windows環境,直接雙擊startup.cmd即可。linux環境請執行./startup.sh -m standalone (standalone代表單機啟動,實際使用應做集群,集群數量三台起步)

查看控制台

nacos默認端口是8848,可不是某手機,8848代表珠穆朗瑪峰的高度(但是現在高度好像是8844了)。

啟動nacos后,訪問localhost:8848/nacos/index.html,可以看到nacos后台。在這里可以對服務和配置做可視化管理(當然現在是空的,一會兒項目啟動就有東西了)。

nacos服務為空

注冊中心

先看看如何作為服務注冊中心

服務注冊

1 項目pom添加依賴

<!-- spring boot 項目 -->
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.2.5.RELEASE</version>
	<relativePath/>
</parent>

<dependencies>
	<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>

	<!-- 服務注冊/發現 -->
	<dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
	<dependencies>
		<!-- spring cloud alibaba 依賴管理 -->
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-alibaba-dependencies</artifactId>
			<version>2.2.1.RELEASE</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

2 application.properties添加配置

# 服務端口
server.port=8081
# 服務名
spring.application.name=service-provider
# 服務注冊中心地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

3 啟動類上添加服務發現注解

@EnableDiscoveryClient
@SpringBootApplication
public class ProviderApplication {

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

}

PS:這里不加@EnableDiscoveryClient也行,Spring Cloud Dalston.SR4版本之后會自動向注冊中心注冊

4 啟動查看

啟動服務,刷新nacos后台就能看到這個服務了

nacos服務一個

服務調用

為了說明服務調用,我們先以同樣的方式配置好另外一個服務

1 pom添加依賴

同上,略

2 application.properties添加配置

# 服務端口
server.port=9091
# 服務名
spring.application.name=service-consumer
# 服務注冊中心地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

3 啟動類

@SpringBootApplication
public class ConsumerApplication {

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

}

4 啟動查看

可以看到,我們有兩個微服務了

nacos服務兩個

5 引入openfeign

openfeign是spring cloud的組件,為微服務之間的調用提供了解決方案。

openfeign的使用也非常簡單,我們在service-consumer項目的基礎上繼續完善

1) pom添加依賴

<dependencies>
	... //省略之前已添加

	<!-- 服務調用 -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-openfeign</artifactId>
	</dependency>
</dependencies>

<dependencyManagement>
	<dependencies>
		... //省略之前已添加
		
		<!-- spring cloud 依賴管理 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-dependencies</artifactId>
			<version>Hoxton.SR3</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

2) 編寫遠程調用類

package com.test.consumer.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient("service-provider")
public interface ProviderFeignService {
	
	@RequestMapping("provider/test")
	public Result providerTest(@RequestBody TestEntity testEntity, @RequestParam String name);
	
}

映射說明: @FeignClient括號里是要調用的微服務名稱,@RequestMapping括號里是被調用微服務的具體api路徑。

傳參說明: 實體類添加@RequestBody,字符串和普通類型添加@RequestParam。

這個service就和我們平時普通的service一樣,在controller使用@Autowired依賴注入即可。

3) 啟動類添加@EnableFeignClients

@EnableFeignClients(basePackages = "com.test.consumer.feign")
@SpringBootApplication
public class ConsumerApplication {

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

}

說明: @EnableFeignClients括號里是要實行遠程調用服務所在的包路徑,即上面遠程調用類所在的包路徑。

現在回到service-provider添加一個測試controller就可以調用成功了

@RestController
@RequestMapping("provider")
public class TestController {

	@PostMapping("test")
	public Result test(TestEntity testEntity, String name) {
		Result result = new Result();
		// do something, balabala
		return result;
	}
}

Result是自定義返回類,略。

原理簡述

服務注冊中心的實現,大概依賴三個重要的定時任務

  1. 客戶端定時任務:定時發送心跳,告訴nacos我還活着
  2. 客戶端定時任務:定時拉取可用服務,放在本地緩存。openfeign調用時自行選用緩存中服務
  3. 服務端定時任務,定時刷新可用列表,踢掉太久沒發心跳的客戶端【默認15秒未發心跳的會被踢出】

小結

以上,我們實現了服務注冊與發現,服務間遠程調用。

配置中心

問題說明

隨着業務越來越復雜,我們會面臨一些問題:

  1. 微服務項目越來越多,配置文件也越來越多,管理起更麻煩
  2. 改動一個配置參數時,需要重新打包微服務重新發布
  3. 有時候希望改動某個參數可以立即生效

接下來,我們使用nacos解決這些問題。

1 添加pom依賴

<dependencies>
	... //省略之前已添加
	
	<!-- 配置中心 -->
	<dependency>
		<groupId>com.alibaba.cloud</groupId>
		<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
	</dependency>
</dependencies>

2 在application.properties設置運行環境

spring.profiles.active=dev

3 新建bootstrap.properties文件

# 服務名
spring.application.name=service-consumer
# 配置中心地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

4 添加注解 @Value + @RefreshScope

@RefreshScope // 自動感知配置文件變化
@RequestMapping("test")
@RestController
public class TestController {
	// 從配置文件獲取屬性值
	@Value("{message}")
	private String message;
	
	@RequestMapping("message")
	public String message() {
		return message;
	}

}

5 去nacos配置中心添加配置文件

nacos配置中心之添加按鈕

nacos配置中心之配置文件

這里Data Id就是配置文件名

6 啟動服務,驗證結果

服務啟動時會去配置中心找文件 ${prefix}-${spring.profile.active}.${file-extension}

  1. prefix默認為spring.application.name,本例中即 service-consumer ;也可以通過配置spring.cloud.nacos.config.prefix來指定
  2. spring.profile.active就是當前環境對應的 profile,本例中即 dev ;如果spring.profile.active不存在,這之前的連接符-也將不存在,文件拼接格式變為${prefix}.${file-extension}
  3. file-extension就是文件后綴,默認為properties;可以通過配置spring.cloud.nacos.config.file-extension來指定,但其值目前只支持propertiesyaml

根據上述說明,服務會去配置中心找的文件就是service-consumer-dev.properties,也即是第5步新增的配置文件。

瀏覽器訪問localhost:9091/test/message就可以看到返回結果為panda,即我們配置文件中的值。

然后去配置中心修改配置文件內容:

nacos配置中心之編輯按鈕

nacos配置中心之配置文件修改

再次訪問localhost:9091/test/message,可以看到返回結果變為panda2

如此,就解決了之前提到的三個問題:

  1. 配置文件和項目包分開,配置文件可統一管理
  2. 配置參數修改后,不需要重新打包項目,直接重啟項目就能讀到修改的值
  3. 對於一些需要立即生效的參數,使用@Value + @RefreshScope組合

7 小結

我們項目的啟動腳本里一般會加上profile,如測試環境java -jar order.jar --spring.profile.active=test,生產環境java -jar order.jar --spring.profile.active=prod。那么,同一個jar包,我們完全不需要任何改動,發布到不同環境,它自己就能讀取到不同環境的配置文件。

一"一個jar包,到處發布"。非常的方便。

namespace & group

我們已經把配置文件從項目中抽離出來了,然而這里仍有麻煩:如果我們有很多微服務,那么就對應有很多配置文件;這些文件還有各自不同環境的版本,也許還有不同業務場景下的版本。如果只是把這么多配置文件都單純放在一起,那么維護起來也會很困難。

1 說明

為了解決配置文件太多不好管理的問題,我們可以使用nacos提供的命名空間(namesapce)和組(group)的概念。

namespace可以看成是一個獨立的一級目錄,namespace之間相互隔離;組可以看成namespace下面的二級目錄,group之間同樣隔離。

之前說,服務啟動后會去配置中心找${prefix}-${spring.profile.active}.${file-extension},其實前面還得加上命名空間和組;即到底是去哪個命名空間下面的哪個組找配置文件。我們沒有配置這兩項,默認是去public下DEFAULT_GROUP找該文件。

而我們創建配置文件時並沒有指定命名空間和組,默認就放在了public下的DEFAULT_GROUP組。

所以才能正常讀取到配置文件。

2 解決方案

根據以上說明,我們可以使用微服務名來作為namespace。如一個商城項目,有訂單微服務(order),商品微服務(product),庫存微服務(stock)等,那我們就分別建立namespace為order, product, stock等。

然后,對於不同的業務場景,我們可以使用group來區分。比如雙11對應的組,我們就叫1111;618對應的組,我們就叫618

我們去命名空間菜單,點擊新建命名空間

nacos配置中心之命名空間菜單

nacos配置中心之新建命名空間

依次添加三個命名空間后,回到配置列表,可以看到新建的命名空間

nacos配置中心之命名空間三個

單擊命名空間,可選中之。我們在其中新建配置文件,組也是在建立配置文件時指定的。

nacos配置中心之命名空間新建配置文件

連續建立不同組不同環境的配置文件,最后應該看起來類似這樣

nacos配置中心之命名空間配置文件一覽

然后其他微服務也如此,建立自己的不同組的不同環境的配置文件。

這里我們可以使用克隆功能,批量復制。

nacos配置中心之命名空間配置文件克隆

結果如下

nacos配置中心之命名空間配置文件克隆結果

如果微服務的配置差別不大的話,可以用這個方式批量復制,再去修改部分參數。

配置文件完成后,再去bootstrap.properties文件指定namespace和group

spring.cloud.nacos.config.group=1111
spring.cloud.nacos.config.namespace=12078634-abb1-4604-8678-45c11db8fe74

這里面的12078634-abb1-4604-8678-45c11db8fe74就是order命名空間后面那一串id

3 小結

以上,我們分離了配置文件和項目。並且能根據微服務和業務分開管理。使得配置維護,項目發布都更加容易。

tip:這里其實有個問題,這個group切換,還是需要修改group后重新發布項目。所以,這里失去了之前說好的"一個jar包,到處發布"的特點。所以,實際使用中,如果沒有特別的業務場景,就使用一個默認group。只指定namespace,那么依舊可以做到不重新打包項目。

ps: 如果有同學知道項目啟動如何指定group,請指正,多謝。

自定義數據庫

默認情況下,nacos是使用了一個嵌入式數據庫。

如果想使用自己的數據庫(目前只支持mysql數據庫)

1 conf目錄下,修改application.properties文件。

spring.datasource.platform=mysql

db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root            #使用的mysql用戶名
db.password=xxx    #使用的mysql連接密碼

2 將conf/nacos-mysql.sql表結構導入到自己的數據庫中

3 重新啟動啟動nacos,會發現之前的配置文件沒有了。重新添加配置文件,在mysql表里看到自己的配置文件內容。

集群

為了保證nacos本身的高可用,可以用三台nacos組成集群。

集群首先要使用自定義數據庫,不然三台集群的配置文件都不能保證一致,集群的基本意義就沒了。

1 復制conf目錄下的cluster.conf.example,重命名為cluster.conf,寫入三台nacos的ip地址

192.168.0.101
192.168.0.102
192.168.0.103

如果在同一台機器上測試,可以設定不同端口

127.0.0.1:8848
127.0.0.1:8858
127.0.0.1:8868

2 復制兩個nacos,放在不同的機器上(單機測試則去conf/application.properties修改端口)。啟動三台nacos。

3 nginx代理配置

# 集群節點
upstream nacos {
 server 192.168.0.101:8848 weight=1;
 server 192.168.0.102:8848 weight=1;
 server 192.168.0.103:8848 weight=1;
}
# 本地集群節點
#upstream nacos {
 #server 127.0.0.1:8848 weight=1;
 #server 127.0.0.1:8858 weight=1;
 #server 127.0.0.1:8868 weight=1;
#}

server {
    listen       80;
    server_name  localhost;
    location /nacos/ {
        #代理
        proxy_pass http://nacos/nacos/;
    }
}

4 訪問
瀏覽器訪問http://localhost/nacos/index.html即可

tip: 保證了Nacos不會有單點故障后,其背后的Mysql最好也做一個主從備份或高可用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM