聊聊SpringBoot使用Nacos進行服務(wù)注冊發(fā)現(xiàn)與配置管理問題
前提
最近由于業(yè)務(wù)發(fā)展,需要調(diào)研一套完善和主流的基礎(chǔ)架構(gòu),進行中臺化(微服務(wù))的實施,考慮到技術(shù)棧切換到SOFAStack。既然整個體系都切換到螞蟻金服的技術(shù)棧,那么自然考慮一些基礎(chǔ)組件如服務(wù)注冊發(fā)現(xiàn)、配置管理等都切換為阿里的技術(shù)棧??紤]到目前比較熱的服務(wù)發(fā)現(xiàn)組件是Nacos,需要調(diào)研SpringBoot服務(wù)接入Nacos的可行性,為以后強制要求新服務(wù)使用SOFAStack + Nacos的技術(shù)棧進行服務(wù)開發(fā)打下基礎(chǔ)。

Nacos簡介
Nacos英文全稱Dynamic Naming and Configuration Service,Na為naming/nameServer即注冊中心,co為configuration即注冊中心,service是指該注冊/配置中心都是以服務(wù)為核心。服務(wù)在nacos是一等公民
下面的簡介來源于Nacos的官網(wǎng):
Nacos致力于幫助您發(fā)現(xiàn)、配置和管理微服務(wù)。Nacos提供了一組簡單易用的特性集,幫助您快速實現(xiàn)動態(tài)服務(wù)發(fā)現(xiàn)、服務(wù)配置、服務(wù)元數(shù)據(jù)及流量管理。
Nacos幫助您更敏捷和容易地構(gòu)建、交付和管理微服務(wù)平臺。Nacos是構(gòu)建以服務(wù)為中心的現(xiàn)代應(yīng)用架構(gòu)(例如微服務(wù)范式、云原生范式)的服務(wù)基礎(chǔ)設(shè)施。
Nacos地圖:

Nacos生態(tài)圖:

從Nacos提供的發(fā)展地圖來看,它基本提供了目前微服務(wù)實施中一些核心問題:監(jiān)控、服務(wù)發(fā)現(xiàn)注冊、配置灰度發(fā)布、配置回滾等等。另外,它在生態(tài)上能夠融入目前主流的K8S、Docker、SpringCloud、Consul、Zookeeper等等(有點像屏蔽底層細節(jié),只需少量配置就可以切換底層架構(gòu)的實現(xiàn)),這一點十分重要。目前Nacos在阿里云上提供了商用版本(記得有前輩說過開源的終極目標(biāo)就是商用,大概如此)。如果在項目中使用的是SpringCloud全家桶,引入Nacos以及它和SpringCloud之間的膠水層,可以完全替代Eureka組件的功能,替代和強化部分Spring Cloud Config的功能。
Nacos服務(wù)部署
Nacos-Server部署相對簡單,它的發(fā)布版本見Github的Releases頁面。下載完成后進行解壓,Windows系下啟動Nacos-Server只需進入解壓后的${解壓目錄}\nacos\bin目錄,執(zhí)行startup.cmd即可,服務(wù)啟動成功的結(jié)果如下:

單機模式在不修改配置的前提下直接啟動,使用的是內(nèi)存數(shù)據(jù)庫,重啟后數(shù)據(jù)會被清空。如果需要數(shù)據(jù)持久化,則需要建立數(shù)據(jù)庫,具體的步驟是:
- 建表的腳本在
${解壓目錄}\nacos\conf目錄下,見schema.sql和nacos-mysql.sql兩個文件。 - 自行通過建表的腳本建立數(shù)據(jù)庫。
- 需要指定數(shù)據(jù)庫,則需要修改
${解壓目錄}\nacos\conf\application.properties,在文件的尾部追加數(shù)據(jù)源的連接配置,下面是官方給出的多數(shù)據(jù)源的例子:
# 需要確保多個數(shù)據(jù)源的用戶名和密碼一致 db.num=2 db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.url.1=jdbc:mysql://11.163.152.9:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.user=nacos_devtest db.password=nacos
測試獲取已經(jīng)注冊的服務(wù):
λ curl -X GET http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName
{"hosts":[],"name":"DEFAULT_GROUP@@nacos.naming.serviceName","clusters":""}訪問http://127.0.0.1:8848/nacos即可打開Nacos-Console,初始的登錄賬號和密碼都是nacos:

更多運維部署相關(guān)的內(nèi)容見文檔運維指南中的一節(jié)。

SpirngBoot應(yīng)用使用Nacos作為注冊中心
SpringBoot應(yīng)用使用Nacos作為注冊中心需要引入依賴nacos-discovery-spring-boot-starter,筆者編寫本文的時候(2020-01-01),該依賴的最新版本為0.2.4,對應(yīng)于SpringBoot的版本為2.0.3.RELEASE,引入如下依賴:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>0.2.4</version>
</dependency>
</dependencies>為了方便起見,筆者把控制器、服務(wù)注冊的代碼都寫在啟動類ProvideApplication中:
@RestController
@SpringBootApplication(scanBasePackages = "club.throwable.provide")
public class ProvideApplication implements CommandLineRunner {
@NacosInjected
private NamingService namingService;
@Value("${spring.application.name}")
private String applicationName;
@Value("${server.port}")
private Integer serverPort;
public static void main(String[] args) {
SpringApplication.run(ProvideApplication.class, args);
}
@GetMapping(path = "/hello")
public String hello(@RequestParam(name = "name") String name) {
return String.format("%s say hello!", name);
}
@Override
public void run(String... args) throws Exception {
// 通過Naming服務(wù)注冊實例到注冊中心
namingService.registerInstance(applicationName, "127.0.0.1", serverPort);
}
}配置文件application-provide.properties內(nèi)容如下:
spring.application.name=provide-service server.port=9092 nacos.discovery.server-addr=127.0.0.1:8848
使用spring.profiles.active=provide啟動ProvideApplication,啟動成功后用瀏覽器打開Nacos-Console:

暫時可知服務(wù)的提供方已經(jīng)注冊成功。接著編寫服務(wù)的消費方代碼,引入的最小依賴和服務(wù)提供方完全一致,編寫啟動類ConsumeApplication如下:
@SpringBootApplication(scanBasePackages = "club.throwable.consume")
public class ConsumeApplication implements CommandLineRunner {
@NacosInjected
private NamingService namingService;
public static void main(String[] args) {
SpringApplication.run(ConsumeApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// 根據(jù)服務(wù)名從注冊中心獲取一個健康的服務(wù)實例
Instance instance = namingService.selectOneHealthyInstance("provide-service");
// 這里只是為了方便才新建RestTemplate實例
RestTemplate template = new RestTemplate();
String url = String.format("http://%s:%d/hello?name=throwable", instance.getIp(), instance.getPort());
String result = template.getForObject(url, String.class);
System.out.println(String.format("請求URL:%s,響應(yīng)結(jié)果:%s", url, result));
}
}消費服務(wù)的配置文件application-consume.properties內(nèi)容如下:
spring.application.name=consume-service server.port=9091 nacos.discovery.server-addr=127.0.0.1:8848
使用spring.profiles.active=consume啟動ConsumeApplication,CommandLineRunner執(zhí)行完畢后控制臺打印:
請求URL:http://127.0.0.1:9092/hello?name=throwable,響應(yīng)結(jié)果:throwable say hello!
這種方式使用起來會感覺模板代碼比較多,不夠簡潔。如果在SpringCloud體系中,結(jié)合Feign客戶端則可以省略這些模板代碼。
SpirngBoot應(yīng)用使用Nacos管理配置
如果使用Nacos進行配置管理,則需要引入nacos-config-spring-boot-starter依賴,筆者編寫本文的時候(2020-01-01),該依賴的最新版本為0.2.4:
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>0.2.4</version>
</dependency>新建一個啟動類ConfigApplication如下:
@RestController
@NacosPropertySource(dataId = "example", autoRefreshed = true)
@SpringBootApplication(scanBasePackages = "club.throwable.config")
public class ConfigApplication {
@NacosValue(value = "${counter:0}", autoRefreshed = true)
public Long counter;
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
@GetMapping(path = "/get")
public String get() {
return String.format("Counter value:%d", counter);
}
}筆者定義了一個長整型的計數(shù)器,設(shè)置了autoRefreshed(自動刷新)為true,新建一個配置文件application-config.properties:
spring.application.name=config-service server.port=9093 nacos.config.server-addr=127.0.0.1:8848
使用spring.profiles.active=config啟動ConfigApplication,啟動成功后通過CURL調(diào)用下面的接口:
λ curl -X GET http://127.0.0.1:9093/get Counter value:0
接著通過Nacos-Console添加一個配置:


點擊發(fā)布按鈕后再次調(diào)用接口:
λ curl -X GET http://127.0.0.1:9093/get Counter value:10086
可見計數(shù)器的值已經(jīng)動態(tài)刷新。配置項里面還有很多高級配置如:指定配置生效的服務(wù)、Beta發(fā)布等等,可以按照合適的場景進行設(shè)置。
另外,Nacos Server提供Open API從而可以使用HTTP客戶端就可以輕松進行配置查詢、配置更新發(fā)布等操作(目前這些API沒有做鑒權(quán),社區(qū)也有人曾提出這樣會引發(fā)安全性問題,Nacos官方已經(jīng)立項在后續(xù)新版本中加入鑒權(quán)的功能,目前建議屏蔽或者僅允許內(nèi)網(wǎng)訪問這些Open API):
- 獲取配置:
curl -X GET http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=${DATA_ID}&group=${GROUP} - 發(fā)布配置:
curl -X POST http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=${DATA_ID}&group=${GROUP}&content=${CONFIG_CONTENT}
小結(jié)
本文只是簡單介紹了SpringBoot中使用Nacos作為注冊中心以及進行配置管理。Nacos項目Github倉庫當(dāng)前(2020-01-01)的star數(shù)已經(jīng)接近10000,社區(qū)也十分活躍,Issues和交流群的響應(yīng)都十分迅速。加之Netflix的部分開源產(chǎn)品如Eureka、Hystrix等已經(jīng)停止迭代,但Nacos還在飛速迭代,甚至已經(jīng)在阿里云衍生出商業(yè)版本,所以筆者認為Nacos值得使用,在相對熟悉它的大部分特性之后會付之于生產(chǎn)環(huán)境中使用。
參考資料:
本文的Demo項目:
下一篇博文會介紹一下SOFAStack中基于SOFABoot、SOFARpc以及Nacos等組件作為基礎(chǔ)架構(gòu)搭建一套微服務(wù)的詳細過程。
到此這篇關(guān)于SpringBoot使用Nacos進行服務(wù)注冊發(fā)現(xiàn)與配置管理的文章就介紹到這了,更多相關(guān)SpringBoot服務(wù)注冊與配置管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot2.6.3讀取不到nacos上的配置文件問題
- springboot集成nacos讀取nacos配置數(shù)據(jù)的原理
- springboot中nacos-client獲取配置的實現(xiàn)方法
- springboot?bootstrap.yml?nacos配置中心問題
- SpringBoot集成Nacos實現(xiàn)注冊中心與配置中心流程詳解
- springboot整合nacos,如何讀取nacos配置文件
- springboot讀取nacos配置文件的實現(xiàn)
- 聊聊SpringBoot整合Nacos自動刷新配置的問題
- 關(guān)于springboot中nacos動態(tài)路由的配置
- SpringBoot使用Nacos動態(tài)配置數(shù)據(jù)源的方法
- SpringBoot使用Nacos配置中心的實現(xiàn)
- springboot集成nacos的配置方法
- Nacos與SpringBoot實現(xiàn)配置管理的開發(fā)實踐
相關(guān)文章
SpringBoot中讀取application.properties配置文件的方法
這篇文章主要介紹了SpringBoot中讀取application.properties配置文件的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-02-02
Springboot內(nèi)置的工具類之CollectionUtils示例講解
這篇文章主要介紹了Springboot內(nèi)置的工具類之CollectionUtils,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-12-12
Java微信公眾平臺開發(fā)(8) 多媒體消息回復(fù)
這篇文章主要為大家詳細介紹了Java微信公眾平臺開發(fā)第八步,微信多媒體消息回復(fù),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04
Intellij IDEA中啟動多個微服務(wù)(開啟Run Dashboard管理)
這篇文章主要介紹了Intellij IDEA中啟動多個微服務(wù)(開啟Run Dashboard管理),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
解決因缺少Log4j依賴導(dǎo)致應(yīng)用啟動失敗的問題
日志是應(yīng)用軟件中不可缺少的部分,Apache的開源項目log4j是一個功能強大的日志組件,提供方便的日志記錄。但這篇文章不是介紹Log4j,這篇文章主要介紹了關(guān)于因缺少Log4j依賴導(dǎo)致應(yīng)用啟動失敗問題的相關(guān)資料,需要的朋友可以參考下。2017-04-04
Java實現(xiàn)將Object轉(zhuǎn)換成指定Class對象的操作代碼
這篇文章主要介紹了Java實現(xiàn)將Object轉(zhuǎn)換成指定Class對象的操作,在Java中,將Object轉(zhuǎn)換為指定類型的Class對象實際上是兩個不同概念的操作,由于你提到的“將Object轉(zhuǎn)換成指定Class對象”可能有些混淆,我將分別展示這兩種操作的示例代碼,需要的朋友可以參考下2024-09-09
關(guān)于SpringMVC對Restful風(fēng)格的支持詳解
Restful就是一個資源定位及資源操作的風(fēng)格,不是標(biāo)準(zhǔn)也不是協(xié)議,只是一種風(fēng)格,是對http協(xié)議的詮釋,下面這篇文章主要給大家介紹了關(guān)于SpringMVC對Restful風(fēng)格支持的相關(guān)資料,需要的朋友可以參考下2022-01-01

