一文秒懂SpringCloud Alibaba中的服務(wù)組件——Nacos
汪偉俊 | 作者
Java技術(shù)迷 | 出品
我們都知道,SpringCloud是微服務(wù)的一站式解決方案,是眾多組件的集合,而因為SpringCloud中幾乎所有的組件使用的都是Netflix公司的產(chǎn)品,其中大部分已經(jīng)進(jìn)入了停止更新或者維護(hù)階段。我們需要一些別的組件來代替它們,基于此,SpringCloud Alibaba誕生了,本篇文章我們就來了解一下SpringCloud Alibaba中的服務(wù)組件——Nacos。
服務(wù)注冊與配置中心-Nacos
nacos是一個更易于構(gòu)建云原生應(yīng)用的動態(tài)服務(wù)發(fā)現(xiàn)、配置管理和服務(wù)管理平臺,在SpringCloud Alibaba中,我們使用nacos進(jìn)行服務(wù)的注冊發(fā)現(xiàn)、服務(wù)的配置管理。
首先下載nacos,官網(wǎng)地址 https://nacos.io/zh-cn/ :

點擊下方的版本說明:

拖動到網(wǎng)頁底部,點擊下載壓縮包,解壓完成后得到如下的目錄結(jié)構(gòu):

其中啟動程序放在bin目錄下,直接執(zhí)行bin目錄中的 startup.cmd 即可啟動nacos:

這樣就表示啟動成功了,此時訪問 http://localhost:8848/nacos :

默認(rèn)的用戶名和密碼均為 nacos ,登錄后即可來到nacos的后臺管理系統(tǒng):

服務(wù)注冊
接下來我們試著編寫一個服務(wù)并將其注冊到nacos中。
首先創(chuàng)建父項目 springcloud-alibaba,將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.wwj</groupId>
<artifactId>springcloud-alibaba</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-alibaba</name>
<description>Demo project for Spring Boot</description>
<packaging>pom</packaging>
<modules>
<module>cloud-provider-payment8001</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
</project>
然后創(chuàng)建支付服務(wù)提供者 cloud-provider-payment8001,修改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>
<artifactId>cloud-provider-payment8001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cloud-provider-payment8001</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.wwj</groupId>
<artifactId>springcloud-alibaba</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
</dependencies>
</dependencyManagement>
......
</project>
重點是引入nacos的依賴,引入依賴后編寫配置文件:
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # nacos的服務(wù)中心地址
service: cloud-provier-payment # 服務(wù)名
server:
port: 8001 # 端口號
需要注意的是服務(wù)名是必須進(jìn)行配置的,配置完成后在啟動類上添加@EnableDiscoveryClient注解:
@EnableDiscoveryClient
@SpringBootApplication
public class CloudProviderPayment8001Application {
public static void main(String[] args) {
SpringApplication.run(CloudProviderPayment8001Application.class, args);
}
}
此時啟動該服務(wù),然后查看nacos的后臺系統(tǒng):

點擊左側(cè)的服務(wù)列表,即可看到我們注冊到nacos中的服務(wù)。然后編寫一個控制器用于模擬業(yè)務(wù):
@RestController
public class PaymentController {
@Value("${server.port}")
private String port;
@GetMapping("/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id) {
return "nacos服務(wù)注冊,端口號:" + port + "\t" + "id:" + id;
}
}
測試一下,訪問 http://localhost:8001/payment/nacos/1:

業(yè)務(wù)正常。接下來創(chuàng)建第二個支付服務(wù) cloud-provider-payment8002 ,代碼直接拷貝剛才的服務(wù)即可,只需修改端口號為8002,其它都一樣。
啟動payment8002,查看nacos后臺:

這樣服務(wù)就注冊成功了。
服務(wù)消費
有了服務(wù)提供者之后,我們理應(yīng)創(chuàng)建服務(wù)消費者來消費這些服務(wù),當(dāng)然,消費者也是要注冊到nacos中的,創(chuàng)建服務(wù) cloud-comsumer-order9000,pom文件依然是引入nacos依賴,然后編寫配置文件:
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # nacos的服務(wù)中心地址
service: cloud-consumer-order # 服務(wù)名
server:
port: 9001 # 端口號
既然是服務(wù)消費,那就少不了服務(wù)調(diào)用,但是nacos已經(jīng)為我們集成了ribbon,當(dāng)我們引入nacos依賴的時候,ribbon依賴也隨之引入進(jìn)來了,所以我們可以直接使用ribbon實現(xiàn)負(fù)載均衡,那么首先就需要將ribbon注冊到容器中:
@Configuration
public class MyApplicationConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
最后編寫控制器并在主啟動類上標(biāo)注@EnableDiscoveryClient注解:
@RestController
public class OrderController {
/**
* 需要調(diào)用的服務(wù)
*/
public static final String SERVER_URL = "http://cloud-provier-payment";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Integer id) {
// 拼接請求地址
String reqUrl = SERVER_URL + "/payment/nacos/" + id;
return restTemplate.getForObject(reqUrl, String.class);
}
}
啟動服務(wù)消費者,首先查看nacos后臺:

服務(wù)注冊成功, 測試一下業(yè)務(wù)代碼,訪問 http://localhost:9001/consumer/payment/nacos/1 :

而且支持負(fù)載均衡,默認(rèn)采用輪詢策略。
OpenFeign
ribbon雖然能夠?qū)崿F(xiàn)客戶端的負(fù)載均衡和服務(wù)調(diào)用,但是稍顯麻煩,缺點也很明顯,需要在Controller層調(diào)用方法請求另外一個服務(wù)的Controller方法。為此,我們可以使用OpenFeign來改進(jìn)這一過程,OpenFeign集成了ribbon,它更側(cè)重服務(wù)之間的調(diào)用,當(dāng)然也默認(rèn)支持負(fù)載均衡。以 cloud-comsumer-order9001 服務(wù)為例,要想使用OpenFeign,我們首先需要引入依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
引入依賴后我們無需注冊RestTemplate,而是來編寫一個接口:
@FeignClient("cloud-provier-payment")
public interface PaymentService {
@GetMapping("/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id);
}
首先在該接口上標(biāo)注 @FeignClient("cloud-provier-payment") 注解,其中值為需要遠(yuǎn)程調(diào)用的服務(wù)名,在接口中定義方法,一般來說,方法的聲明與需要調(diào)用的方法聲明一致。
然后在啟動類上標(biāo)注@EnableFeignClients注解:
@EnableDiscoveryClient
@EnableFeignClients("com.wwj.cloudcomsumer.order.service")
@SpringBootApplication
public class CloudComsumerOrder9001Application {
public static void main(String[] args) {
SpringApplication.run(CloudComsumerOrder9001Application.class, args);
}
}
若是接口在啟動類當(dāng)前包及其子包下,則無需配置注解的值;接下來就可以編寫業(yè)務(wù)方法了:
@RestController
public class OrderController {
@Autowired
private PaymentService paymentService;
@GetMapping("/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Integer id) {
return paymentService.getPayment(id);
}
}
將接口直接注入進(jìn)來,然后調(diào)用接口中的方法即可。啟動項目,測試業(yè)務(wù):
服務(wù)配置
在前面我們就說過,nacos既是服務(wù)的注冊中心,也是服務(wù)的配置中心,接下來看看nacos如何對服務(wù)進(jìn)行配置。
首先創(chuàng)建一個新的服務(wù) cloud-config2001,然后引入依賴:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-config</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
我們同樣需要將服務(wù)注冊到nacos中,并且還需要額外配置nacos的配置中心:
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # nacos的服務(wù)中心地址
service: cloud-config2001 # 服務(wù)名
config:
server-addr: 127.0.0.1:8848 # nacos的配置中心地址
file-extension: yaml # 指定配置文件格式為yaml
prefix: cloud-config2001 # DataId前綴
server:
port: 2001 # 端口號
這個配置文件有講究,我們需要創(chuàng)建一個名為 bootstrap.yml 的配置文件,這是因為我們需要優(yōu)先去配置中心獲取所需的配置,當(dāng)配置中心沒有配置時,才使用本地的配置,而bootstrap.yml配置文件的優(yōu)先級高于其它命名的配置文件,故需將配置寫在bootstrap.yml中。
不要忘了在啟動類上標(biāo)注@EnableDiscoveryClient 注解。最后編寫一個方法進(jìn)行測試:
@RestController
@RefreshScope // 支持nacos的動態(tài)刷新功能
public class ConfigController {
@Value("${config.msg}")
private String msg;
@GetMapping("/get/msg")
public String getMsg() {
return msg;
}
}
在本地我們并沒有編寫關(guān)于config.msg的配置信息,只需在nacos中編寫配置即可,步驟如下。首先點擊左側(cè)導(dǎo)航欄的配置列表,然后點擊右側(cè)的+號:

特別需要注意接下來這一步:

最底下的是配置的內(nèi)容,最上面的是Data ID,這個Data ID非常有講究,它遵循這樣的一個命名規(guī)范:
${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
在項目中我們并沒有配置 ${spring.application.name} ,但我們配置了Data ID的前綴: prefix: cloud-config2001 ,這兩個必須選其中一個進(jìn)行配置;我們也沒有配置 ${spring.profiles.active} ,然后配置了文件格式為yaml,所以Data ID為 cloud-config2001.yaml 。若是我們配置了:
spring:
profiles:
active: dev # 開發(fā)環(huán)境
則Data ID為:cloud-config2001-dev.yaml ,最后千萬記得點擊發(fā)布配置才能生效。啟動項目,測試一下:

加上我們在控制器上標(biāo)注了@RefreshScope注解,所以在nacos配置中心里修改配置后,就能夠立馬在項目中生效,無需重新啟動項目。
配置管理
nacos作為配置中心,除了能夠提供配置外,它還具有非常強大的功能,比如命名空間、配置分組等等,首先說說命名空間。命名空間是用來區(qū)分部署環(huán)境的,一個項目往往需要經(jīng)歷開發(fā)、測試、維護(hù)三個階段,每個階段的配置內(nèi)容可能不盡相同,為此,可以創(chuàng)建三個命名空間來分別接管這三個階段的配置;默認(rèn)情況下會有一個 public 命名空間。然后是Data ID,前面我們已經(jīng)了解過Data ID的組成結(jié)構(gòu),所以我們可以直接通過Data ID的不同來區(qū)分不同環(huán)境的配置,比如:
?cloud-config2001-dev.yaml?cloud-config2001-test.yaml?cloud-config2001-prod.yaml
此時我們就能通過修改:
spring:
profiles:
active: dev
# active: test
# active: prod
來分別獲取三個配置文件的配置。
接下來我們再來看看分組,默認(rèn)情況下我們會有一個 DEFAULT_GROUP 分組,新建的配置文件都會被存放在該分組下,通過分組我們也能夠區(qū)分部署環(huán)境的配置信息:

這三個配置文件名相同,但是分組分別屬于開發(fā)、測試和生產(chǎn)環(huán)境,然后通過 group 屬性指定即可:
spring:
cloud:
nacos:
config:
group: DEV_GROUP # 指定分組
# group: TEST_GROUP
# group: PROD_GROUP
最后是命名空間,通過命名空間,我們?nèi)匀荒軌驅(qū)崿F(xiàn)同樣的效果:

點擊導(dǎo)航欄的命名空間,然后點擊右側(cè)的新建命名空間:

創(chuàng)建好命名空間后,nacos會為每個命名空間分配id:

然后配置一下命名空間:
spring:
cloud:
nacos:
config:
group: DEV_GROUP # 指定分組
namespace: d7e672f8-441e-449b-a143-1eca69122daa # 命名空間ID
此時服務(wù)會去尋找該命名空間下的指定分組的配置文件,若有環(huán)境指定,也需要加上,然后在nacos中新建配置文件:

在指定命名空間下創(chuàng)建配置文件即可。
本文作者:汪偉俊 為Java技術(shù)迷專欄作者 投稿,未經(jīng)允許請勿轉(zhuǎn)載。

往 期 推 薦 1、最牛逼的 Java 日志框架,性能無敵,橫掃所有對手! 2、把Redis當(dāng)作隊列來用,真的合適嗎? 3、驚呆了,Spring Boot居然這么耗內(nèi)存!你知道嗎? 4、牛逼哄哄的 BitMap,到底牛逼在哪? 5、全網(wǎng)最全 Java 日志框架適配方案!還有誰不會? 6、30個IDEA插件總有一款適合你 7、Spring中毒太深,離開Spring我居然連最基本的接口都不會寫了

點分享

點收藏

點點贊

點在看


