Nacos簡介
Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理。Nacos 幫助更敏捷和容易地構建、交付和管理微服務平台。 Nacos 是構建以“服務”為中心的現代應用架構 (例如微服務范式、雲原生范式) 的服務基礎設施。
Nacos提供兩個主要的能力:
- 服務注冊中心
Nacos 支持基於 DNS 和基於 RPC 的服務發現。
服務提供者使用原生SDK、OpenApi注冊 Service 后,服務消費者可以使用DNS TODO或HTTP&API查找和發現服務。
Nacos提供對服務的健康監測,阻止向不健康的服務或者實例發送請求。
- 動態配置中心
動態配置服務可以讓您以中心化、外部化和動態化的方式管理所有環境的應用配置和服務配置。
動態配置消除了配置變更時重新部署應用和服務的需要,讓配置管理變得更加高效和敏捷。
配置中心化管理讓實現無狀態服務變得更簡單,讓服務按需彈性擴展變得更容易。
中文官網 : https://nacos.io/zh-cn/
GitHub : https://github.com/alibaba/nacos
部署方式
Nacos支持三種部署方式
單機模式:用戶測試和單機使用。
集群模式:生產環境使用,保證服務的高可用。
多集群模式: 用於多數據中心場景。
本地測試使用單機模式部署
Linux/Unix/Mac: 運行命令 startup.sh -m standalone
Windows: 雙擊 startup.cmd 文件
另外單機模式還支持mysql(默認使用內嵌數據庫),具體的操作步驟:
· 1.安裝數據庫,版本要求:5.6.5+
· 2.初始化mysql數據庫,數據庫初始化文件:nacos-mysql.sql
· 3.修改conf/application.properties文件,增加支持mysql數據源配置(目前只支持mysql),添加mysql數據源的url、用戶名和密碼。
spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.user=nacos_devtest db.password=youdontknow
單機模式啟動nacos,nacos所有寫嵌入式數據庫的數據都寫到了mysql。
SpringCloud使用Nacos實現服務的注冊與發現
服務注冊
1. 首先進行Maven配置,在pom文件中引入SpringCloud-Nacos的依賴。
<?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> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.13.RELEASE</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>service-provider</artifactId> <version>0.0.1-SNAPSHOT</version> <name>service-provider</name> <description>Demo project for Service Provider</description> <properties> <java.version>1.8</java.version> <nacos.version>2.1.2.RELEASE</nacos.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>${nacos.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2. 配置Nacos連接信息,新建application.yaml配置文件。
server: port: 7001 spring: application: name: service-provider cloud: nacos: discovery: server-addr: 127.0.0.1:8848 namespace: d95b5b39-cc31-422b-895d-6b56aed294c8 group: tydd
3. 配置啟動類,添加SpringCloud的服務注冊發現標簽(@EnableDiscoveryClient)。
1 @SpringBootApplication 2 @EnableDiscoveryClient 3 public class ServiceProviderApplication { 4 public static void main(String[] args) { 5 SpringApplication.run(ServiceProviderApplication.class, args); 6 } 7 }
啟動項目時在日志中可以看到服務注冊信息日志 (NacosServiceRegistry : nacos registry, tydd service-provider 199.168.24.239:7001 register finished)。服務啟動成功在Nacos控制台中查看到服務的注冊信息。服務的注冊信息詳情中可以查看到實例的IP、端口、健康狀態、自定義元數據等信息。(控制台訪問地址:http://127.0.0.1:8848/nacos/index.html#/login)
圖:服務注冊信息
圖:服務實例信息
通常微服務架構中,一個服務一般會部署多個實例來確保服務的高可用和提升服務的性能。下面演示服務注冊多個實例的場景。
創建配置文件 application-A.yaml 和 application-B.yaml ,配置項不變,只修改端口號避免端口重復(因為在是一台機器上演示,所以端口號要區分)。
然后執行Maven打包命令生成Jar包,通過命令啟動兩個項目實例 java -jar service-provider-0.0.1-SNAPSHOT.jar --spring.profiles.active=A / java -jar service-provider-0.0.1-SNAPSHOT.jar --spring.profiles.active=B ,項目啟動成功在控制台中可以看到 service-provide 服務有兩個實例注冊成功,如下圖所示。
服務發現
通過一個簡單的例子演示如何在Spring Cloud項目中啟用Nacos的服務發現功能。
1. 首先創建新的應用 service-consumer,應用的Maven依賴和application.yaml配置如下。
<?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> <packaging>pom</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.13.RELEASE</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>service-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>service-consumer</name> <description>Demo project for service-consumer</description> <properties> <java.version>1.8</java.version> <nacos.version>2.1.2.RELEASE</nacos.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>${nacos.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
server: port: 7003 spring: application: name: service-consumer cloud: nacos: discovery: server-addr: 127.0.0.1:8848 namespace: d95b5b39-cc31-422b-895d-6b56aed294c8 group: tydd
2. 創建啟動類 ServerConsumerApplication,添加Spring原生注解 @EnableDiscoveryClient ,並注入 RestTemplate 用於調用注冊的服務。
@SpringBootApplication @EnableDiscoveryClient public class ServerConsumerApplication { public static void main(String[] args) { SpringApplication.run(ServerConsumerApplication.class, args); } @LoadBalanced @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
3. 創建測試接口,在應用service-consumer中創建測試接口,調用service-provider服務。
@RestController @RequestMapping(value = "consumer") public class ConsumerController { private static String SERVICE_NAME = "service-provider"; @Autowired private RestTemplate restTemplate; @GetMapping(value = "provider/info") public String getClientServerResult() { return restTemplate.getForObject("http://" + SERVICE_NAME + "/provider/info", String.class); } }
啟動service-consumer應用后,在Nacos控制台匯總可以看到新的服務注冊成功,並且意味着可以消費其他的服務。調用測試接口,獲取 service-provider服務的實例信息。接口返回信息如下所示:
1 Service Info, service name : service-provider, port : 7001 2 Service Info, service name : service-provider, port : 7002 3 Service Info, service name : service-provider, port : 7001 4 Service Info, service name : service-provider, port : 7002
每一次調用返回的實例信息都不相同,是因為集成的 spring-cloud-riboon 客戶端負載均衡的默認模式是輪詢模式。
自定義元數據
在啟動類中添加如下代碼,添加我們的自定義元數據,記錄實例啟動時間。
1 @Bean 2 @ConditionalOnMissingBean 3 public NacosDiscoveryProperties nacosProperties() { 4 return new NacosDiscoveryProperties(); 5 } 6 7 @Bean 8 @ConditionalOnMissingBean 9 @ConditionalOnProperty(value = {"spring.cloud.nacos.discovery.watch.enabled"}, matchIfMissing = true) 10 public NacosWatch nacosWatch(NacosDiscoveryProperties nacosDiscoveryProperties) { 11 Map<String, String> metadataMap = nacosDiscoveryProperties.getMetadata(); 12 if (metadataMap == null) { 13 metadataMap = new HashMap<>(); 14 } 15 metadataMap.put("startup.time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); 16 metadataMap.put("spring.profiles.active", profile); 17 nacosDiscoveryProperties.setMetadata(metadataMap); 18 return new NacosWatch(nacosDiscoveryProperties); 19 }
重啟服務后,可以在控制台中看到新添加的自定義元數據。
配置中心
使用Nacos的配置中心功能,通過Nacos去進行項目配置。
1. 首先新建配置文件bootstrap.yaml,注意這里不是application.yaml,原因是Nacos同SpringBoot一樣,在項目初始化的時要先從配置中心拉取配置文件,Spring的加載是存在優先順序的,bootstrap優先級高於application。
配置文件內容如下:
1 server: 2 port: 7001 #端口 3 spring: 4 application: 5 name: service-provider #服務名稱 6 profiles: 7 active: dev #環境 8 cloud: 9 nacos: 10 config: 11 file-extension: yaml # 配置后綴 12 server-addr: 127.0.0.1:8848 #配置服務地址 13 namespace: d95b5b39-cc31-422b-895d-6b56aed294c8 #配置文件命名空間ID 14 group: tydd #配置分組 15 prefix: ${spring.application.name} 16 discovery: 17 server-addr: ${spring.cloud.nacos.config.server-addr} #注冊服務Nacos地址 18 namespace: ${spring.cloud.nacos.config.namespace} #注冊服務命名空間ID 19 group: tydd #注冊服務分組
說明:在 Nacos Spring Cloud 中,dataId 的完整格式如下:
${prefix}-${spring.profile.active}.${file-extension}
spring.application.name 它是構成Nacos配置管理dataId字段的一部分。
spring.profile.active 當前環境對應的profile注意:當 spring.profile.active為空時,對應的連接符 - 也將不存在,dataId 的拼接格式變成 ${prefix}.${file-extension}。
file-exetension 為配置內容的數據格式,可以通過配置項 spring.cloud.nacos.config。
file-extension 來配置。目前只支持 properties 和 yaml 類型。
2. 寫好配置文件后,在pom文件中加入Naocs-config的Maven引用。
1 <dependency> 2 <groupId>com.alibaba.cloud</groupId> 3 <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> 4 <version>${nacos.version}</version> 5 </dependency>
3. 添加Nacos配置文件,在Nacos控制台的創建命名空間dev,創建成功后會生成一個命名空間ID(將這個ID寫入到bootstrap.yaml文件中的spring.cloud.nacos.config.namespace項)。然后在“配置列表”菜單中選擇對應的命名空間,創建配置文件service-provider.yaml。
圖:創建命名空間
圖:創建配置文件
4. 創建測試接口,讀取Nacos配置。通過Spring的原生注解 @Value 注入配置項的值,並通過 @RefreshScop 實現配置自動更新。
1 @RefreshScope 2 @RestController 3 public class NacosConfigController { 4 5 @Value("${provider.name}") 6 private String providerName; 7 8 @RequestMapping(value = "config/getValue") 9 public String getConfigValue() { 10 return this.providerName; 11 } 12 }
調用接口獲取到Nacos的配置值,如下圖所示。
如果在Naocs控制台修改了配置值,會更新本地的配置文件,通過日志可以看出刷新了修改配置項的值。
o.s.c.e.event.RefreshEventListener : Refresh keys changed: [provider.name]
再次請求接口可以驗證配置項的值已經更新。