Nacos 註冊中心
一、概述
1.關鍵特性
(1)服務發現和服務健康監測
Nacos 支持基於 DNS 和基於 RPC 的服務發現。服務提供者使用 原生 SDK、OpenAPI、或一個 獨立的 Agent TODO 註冊 Service 後,服務消費者可以使用 DNS TODO 或 HTTP&API 查找和發現服務。
Nacos 提供對服務的實時的健康檢查,阻止向不健康的主機或服務實例發送請求。Nacos 支持傳輸層 (PING 或 TCP) 和應用層 (如 HTTP、MySQL、用戶自定義)的健康檢查。 對於複雜的雲環境和網絡拓撲環境中(如 VPC、邊緣網絡等)服務的健康檢查,Nacos 提供了 agent 上報模式和服務端主動檢測 2 種健康檢查模式。Nacos 還提供了統一的健康檢查儀表盤,幫助您根據健康狀態管理服務的可用性及流量。
(2)動態配置服務
動態配置服務可以讓您以中心化、外部化和動態化的方式管理所有環境的應用配置和服務配置。動態配置消除了配置變更時重新部署應用和服務的需要,讓配置管理變得更加高效和敏捷。配置中心化管理讓實現無狀態服務變得更簡單,讓服務按需彈性擴展變得更容易。
Nacos 提供了一個簡潔易用的 UI 幫助您管理所有的服務和應用的配置。Nacos 還提供包括配置版本跟蹤、金絲雀發佈、一鍵回滾配置以及客戶端配置更新狀態跟蹤在內的一系列開箱即用的配置管理特性,幫助您更安全地在生產環境中管理配置變更和降低配置變更帶來的風險。
(3)動態 DNS 服務
動態 DNS 服務支持權重路由,讓您更容易地實現中間層負載均衡、更靈活的路由策略、流量控制以及數據中心內網的簡單 DNS 解析服務。動態 DNS 服務還能讓您更容易地實現以 DNS 協議爲基礎的服務發現,以幫助您消除耦合到廠商私有服務發現 API 上的風險。
Nacos 提供了一些簡單的 DNS APIs TODO 幫助您管理服務的關聯域名和可用的 IP:PORT 列表.
(4)服務及其元數據管理
Nacos 能讓您從微服務平臺建設的視角管理數據中心的所有服務及元數據,包括管理服務的描述、生命週期、服務的靜態依賴分析、服務的健康狀態、服務的流量管理、路由及安全策略、服務的 SLA 以及最首要的 metrics 統計數據。
二、Nacos 地圖
- 特性大圖:要從功能特性,非功能特性,全面介紹我們要解的問題域的特性訴求
- 架構大圖:通過清晰架構,讓您快速進入 Nacos 世界
- 業務大圖:利用當前特性可以支持的業務場景,及其最佳實踐
- 生態大圖:系統梳理 Nacos 和主流技術生態的關係
- 優勢大圖:展示 Nacos 核心競爭力
- 戰略大圖:要從戰略到戰術層面講 Nacos 的宏觀優勢
三、Nacos 架構
1基本架構及概念
(1)服務 (Service)
服務是指一個或一組軟件功能(例如特定信息的檢索或一組操作的執行),其目的是不同的客戶端可以爲不同的目的重用(例如通過跨進程的網絡調用)。Nacos 支持主流的服務生態,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service.
(2)服務註冊中心 (Service Registry)
服務註冊中心,它是服務,其實例及元數據的數據庫。服務實例在啓動時註冊到服務註冊表,並在關閉時註銷。服務和路由器的客戶端查詢服務註冊表以查找服務的可用實例。服務註冊中心可能會調用服務實例的健康檢查 API 來驗證它是否能夠處理請求。
(3)服務元數據 (Service Metadata)
服務元數據是指包括服務端點 (endpoints)、服務標籤、服務版本號、服務實例權重、路由規則、安全策略等描述服務的數據
(4)服務提供方 (Service Provider)
是指提供可複用和可調用服務的應用方
(5)服務消費方 (Service Consumer)
是指會發起對某個服務調用的應用方
(6)配置 (Configuration)
在系統開發過程中通常會將一些需要變更的參數、變量等從代碼中分離出來獨立管理,以獨立的配置文件的形式存在。目的是讓靜態的系統工件或者交付物(如 WAR,JAR 包等)更好地和實際的物理運行環境進行適配。配置管理一般包含在系統部署的過程中,由系統管理員或者運維人員完成這個步驟。配置變更是調整系統運行時的行爲的有效手段之一。
(7)配置管理 (Configuration Management)
在數據中心中,系統中所有配置的編輯、存儲、分發、變更管理、歷史版本管理、變更審計等所有與配置相關的活動統稱爲配置管理。
(8)名字服務 (Naming Service)
提供分佈式系統中所有對象 (Object)、實體 (Entity) 的 “名字” 到關聯的元數據之間的映射管理服務,例如 ServiceName -> Endpoints Info, Distributed Lock Name -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服務發現和 DNS 就是名字服務的 2 大場景。
(9)配置服務 (Configuration Service)
在服務或者應用運行過程中,提供動態配置或者元數據以及配置管理的服務提供者。
2.邏輯架構及其組件介紹
- 服務管理: 實現服務 CRUD,域名 CRUD,服務健康狀態檢查,服務權重管理等功能
- 配置管理: 實現配置管 CRUD,版本管理,灰度管理,監聽管理,推送軌跡,聚合數據等功能
- 元數據管理: 提供元數據 CURD 和打標能力
- 插件機制: 實現三個模塊可分可合能力,實現擴展點 SPI 機制
- 事件機制: 實現異步化事件通知,sdk 數據變化異步通知等邏輯
- 日誌模塊: 管理日誌分類,日誌級別,日誌可移植性(尤其避免衝突),日誌格式,異常碼 + 幫助文檔
- 回調機制: sdk 通知數據,通過統一的模式回調用戶處理。接口和數據結構需要具備可擴展性
- 尋址模式: 解決 ip,域名,nameserver、廣播等多種尋址模式,需要可擴展
- 推送通道: 解決 server 與存儲、server 間、server 與 sdk 間推送性能問題
- 容量管理: 管理每個租戶,分組下的容量,防止存儲被寫爆,影響服務可用性
- 流量管理: 按照租戶,分組等多個維度對請求頻率,長鏈接個數,報文大小,請求流控進行控制
- 緩存機制: 容災目錄,本地緩存,server 緩存機制。容災目錄使用需要工具
- 啓動模式: 按照單機模式,配置模式,服務模式,dns 模式,或者 all 模式,啓動不同的程序 + UI
- 一致性協議: 解決不同數據,不同一致性要求情況下,不同一致性機制
- 存儲模塊: 解決數據持久化、非持久化存儲,解決數據分片問題
- Nameserver: 解決 namespace 到 clusterid 的路由問題,解決用戶環境與 nacos 物理環境映射問題
- CMDB: 解決元數據存儲,與三方 cmdb 系統對接問題,解決應用,人,資源關係
- Metrics: 暴露標準 metrics 數據,方便與三方監控系統打通
- Trace: 暴露標準 trace,方便與 SLA 系統打通,日誌白平化,推送軌跡等能力,並且可以和計量計費系統打通
- 接入管理: 相當於阿里雲開通服務,分配身份、容量、權限過程
- 用戶管理: 解決用戶管理,登錄,sso 等問題
- 權限管理: 解決身份識別,訪問控制,角色管理等問題
- 審計系統: 擴展接口方便與不同公司審計系統打通
- 通知系統: 核心數據變更,或者操作,方便通過 SMS 系統打通,通知到對應人數據變更
- OpenAPI: 暴露標準 Rest 風格 HTTP 接口,簡單易用,方便多語言集成
- Console: 易用控制檯,做服務管理、配置管理等操作
- SDK: 多語言 sdk
- Agent: dns-f 類似模式,或者與 mesh 等方案集成
- CLI: 命令行對產品進行輕量化管理,像 git 一樣好用
四.Nacos 安裝
1.概述
Nacos 官方提供了 Docker 版本,方便我們快速部署。
2.操作步驟
mkdir /usr/local/docker
cd /usr/local/docker
git clone https://github.com/nacos-group/nacos-docker.git #git克隆
cd nacos-docker/
docker-compose -f example/standalone-mysql.yaml up -d #單機模式
docker-compose -f example/standalone-mysql.yaml logs -f #可選:查看日誌
3.訪問頁面
http://192.168.88.135:8848/nacos #賬號密碼均爲nacos
4.採坑
在安裝nacos時,運行完docker-compose 命令後,docker容器中的兩個mysql容器無法啓動.
SELinux 主要作用就是最大限度地減小系統中服務進程可訪問的資源(最小權限原則)。
vi /etc/sysconfig/selinux
更改內容 SELINUX=disabled
reboot #重啓
五.服務註冊與發現
1.概述
這裏實現一個簡單的 echo service
演示如何在您的 Spring Cloud 項目中啓用 Nacos 的服務發現功能,如下圖示:
2.創建父工程
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lxm</groupId>
<artifactId>hello-spring-cloud-alibaba</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-cloud-alibaba</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<packaging>pom</packaging>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
<spring-cloud-alibaba.version>0.9.0.RELEASE</spring-cloud-alibaba.version>
</properties>
<!--開源協議-->
<licenses>
<license>
<name>Apache 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>lay3399</id>
<name>XiaoMeng Lu</name>
<email>[email protected]</email>
</developer>
</developers>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestone</id>
<name>Spring Milestone</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshot</id>
<name>Spring Snapshot</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestone</id>
<name>Spring Milestone</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshot</id>
<name>Spring Snapshot</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
3.服務提供者
服務提供方: 是指提供可複用和可調用服務的應用方
POM
創建一個名爲 hello-spring-cloud-alibaba-provider
的服務提供者項目,pom.xml
配置如下:
<?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">
<parent>
<artifactId>hello-spring-cloud-alibaba</artifactId>
<groupId>com.lxm</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hello-spring-cloud-alibaba-provider</artifactId>
<packaging>jar</packaging>
<licenses>
<license>
<name>Apache 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>lay3399</id>
<name>XiaoMeng Lu</name>
<email>[email protected]</email>
</developer>
</developers>
<dependencies>
<!-- Spring Boot Begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot End -->
<!-- Spring Cloud Begin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud End -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.funtl.spring.cloud.alibaba.provider.ProviderApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
application:
# 服務名
name: service-provider
cloud:
nacos:
discovery:
# 服務註冊中心
server-addr: (你的nacos服務器地址):8848
server:
# 服務端口
port: 8070
management:
# 端點檢查(健康檢查)
endpoints:
web:
exposure:
include: "*"
Application啓動器
通過 Spring Cloud 原生註解 @EnableDiscoveryClient
開啓服務註冊發現功能
package com.lxm.spring.cloud.alibaba.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
controller
package com.lxm.spring.cloud.alibaba.provider.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Hello Nacos Provider " + string;
}
}
服務端點檢查
健康檢查: 以指定方式檢查服務下掛載的實例 (Instance) 的健康度,從而確認該實例 (Instance) 是否能提供服務。根據檢查結果,實例 (Instance) 會被判斷爲健康或不健康。對服務發起解析請求時,不健康的實例 (Instance) 不會返回給客戶端。
通過瀏覽器訪問 http://localhost:8070/actuator/nacos-discovery
{
"subscribe": [
{
"jsonFromServer": "",
"name": "service-provider",
"groupName": "DEFAULT_GROUP",
"clusters": null,
"cacheMillis": 1000,
"hosts": [],
"lastRefTime": 0,
"checksum": "",
"allIPs": false,
"key": "service-provider",
"valid": true,
"keyEncoded": "service-provider"
},
{
"jsonFromServer": "",
"name": "service-consumer",
"groupName": "DEFAULT_GROUP",
"clusters": null,
"cacheMillis": 1000,
"hosts": [],
"lastRefTime": 0,
"checksum": "",
"allIPs": false,
"key": "service-consumer",
"valid": true,
"keyEncoded": "service-consumer"
}
],
"NacosDiscoveryProperties": {
"serverAddr": "192.168.141.132:8848",
"endpoint": "",
"namespace": "",
"watchDelay": 30000,
"logName": "",
"service": "service-provider",
"weight": 1,
"clusterName": "DEFAULT",
"namingLoadCacheAtStart": "false",
"metadata": {
"preserved.register.source": "SPRING_CLOUD"
},
"registerEnabled": true,
"ip": "192.168.141.1",
"networkInterface": "",
"port": 8070,
"secure": false,
"accessKey": "",
"secretKey": ""
}
}
4.服務消費者
服務消費方: 是指會發起對某個服務調用的應用方
服務消費者的創建與服務提供者大同小異,這裏採用最原始的一種方式,即顯示的使用 LoadBalanceClient 和 RestTemplate 結合的方式來訪問
POM
創建一個名爲 hello-spring-cloud-alibaba-consumer
的服務消費者項目,pom.xml
配置如下:
<?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>
<parent>
<artifactId>hello-spring-cloud-alibaba</artifactId>
<groupId>com.lxm</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>hello-spring-cloud-alibaba-consumer</artifactId>
<packaging>jar</packaging>
<licenses>
<license>
<name>Apache 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>lay3399</id>
<name>XiaoMeng Lu</name>
<email>[email protected]</email>
</developer>
</developers>
<dependencies>
<!-- Spring Boot Begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot End -->
<!-- Spring Cloud Begin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud End -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.funtl.spring.cloud.alibaba.consumer.ConsumerApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
application:
# 服務名
name: service-consumer
cloud:
nacos:
discovery:
# 服務註冊中心
server-addr: 192.168.88.132:8848
server:
# 服務端口
port: 8080
management:
# 端點檢查(健康檢查)
endpoints:
web:
exposure:
include: "*"
Application
通過 Spring Cloud 原生註解 @EnableDiscoveryClient
開啓服務註冊發現功能
package com.lxm.spring.cloud.alibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
Configuration
package com.lxm.spring.cloud.alibaba.configure;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConsumerConfiguration {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
controller
package com.lxm.spring.cloud.alibaba.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
private final RestTemplate restTemplate;
@Autowired
public TestController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping(value = "/echo/{str}")
public String echo(@PathVariable String str) {
// 使用服務名請求服務提供者
return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
}
}
安全檢查同上
結果
訪問消費者的接口http://localhost:8080/echo/hi,消費者則通過註冊中心請求提供者服務並返回數據
六、Feign
Feign 是一個聲明式的僞 HTTP 客戶端,它使得寫 HTTP 客戶端變得更簡單。使用 Feign,只需要創建一個接口並註解。它具有可插拔的註解特性,可使用 Feign 註解和 JAX-RS 註解。Feign 支持可插拔的編碼器和解碼器。Feign 默認集成了 Ribbon,Nacos 也很好的兼容了 Feign,默認實現了負載均衡的效果
- Feign 採用的是基於接口的註解
- Feign 整合了 Ribbon
1.pom
在 hello-spring-cloud-alibaba-consumer
項目中增加 org.springframework.cloud:spring-cloud-starter-openfeign
依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.Application
通過 @EnableFeignClients
註解開啓 Feign 功能
package com.lxm.spring.cloud.alibaba;
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 ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
3.Service
創建業務結構,通過 @FeignClient("服務名")
註解來指定調用哪個服務
package com.lxm.spring.cloud.alibaba.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "service-provider")
public interface EchoService {
@GetMapping(value = "/echo/{string}")
String echo(@PathVariable("string") String string);
}
4.controller
@GetMapping(value = "/feign/echo/{str}")
public String echofeign(@PathVariable String str) {
return echoService.echo(str);
}
5.驗證是否成功
通過瀏覽器訪問 http://localhost:8080/feign/echo/hi
七、分佈式配置中心
1.概述
在分佈式系統中,由於服務數量巨多,爲了方便服務配置文件統一管理,實時更新,所以需要分佈式配置中心組件
2.什麼是 Nacos Config
Nacos 提供用於存儲配置和其他元數據的 key/value 存儲,爲分佈式系統中的外部化配置提供服務器端和客戶端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 應用的外部屬性配置。
Spring Cloud Alibaba Nacos Config 是 Spring Cloud Config Server 和 Client 的替代方案,客戶端和服務器上的概念與 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 階段,配置被加載到 Spring 環境中。當應用程序通過部署管道從開發到測試再到生產時,您可以管理這些環境之間的配置,並確保應用程序具有遷移時需要運行的所有內容。
3.接入配置中心
pom
以 service-consumer
項目爲例,修改 pom.xml
,引入 Nacos Config Starter
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
Controller
完成上述兩步後,應用會從 Nacos Config 中獲取相應的配置,並添加在 Spring Environment 的 PropertySources 中。這裏我們使用 @Value
註解來將對應的配置注入到 TestEchoController
的 username
字段,並添加 @RefreshScope
打開動態刷新功能
package com.lxm.spring.cloud.alibaba.controller;
import com.lxm.spring.cloud.alibaba.service.EchoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RefreshScope
public class TestController {
private final RestTemplate restTemplate;
@Autowired
private EchoService echoService;
@Autowired
public TestController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping(value = "/echo/{str}")
public String echo(@PathVariable String str) {
// 使用服務名請求服務提供者
return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
}
@GetMapping(value = "/feign/echo/{str}")
public String echofeign(@PathVariable String str) {
return echoService.echo(str);
}
//這裏是config驗證代碼
@Value("${user.name}")
private String username;
@GetMapping(value = "/config")
public String config() {
return echoService.echo(username);
}
}
使用控制檯發佈配置
通過瀏覽器訪問 nacos Server 點擊“配置管理”-“配置列表”添加配置
Data ID: service-consumer-config.yaml
配置內容
spring:
application:
# 服務名
name: service-consumer
cloud:
nacos:
discovery:
# 服務註冊中心
server-addr: {服務註冊中心服務器ip}:8848
server:
# 服務端口
port: 8080
management:
# 端點檢查(健康檢查)
endpoints:
web:
exposure:
include: "*"
user:
name: "我是配置服務A~"
例圖:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xKF6lL2c-1570002181571)(F:\工作\筆記\筆記\SpringCloudAli\img\regiest.png)]
修改客戶端配置
創建名爲 bootstrap.properties
的配置文件並刪除之前創建的 application.yml
配置文件
spring.application.name=service-consumer-config
spring.cloud.nacos.config.server-addr=192.168.88.132:8848
spring.cloud.nacos.config.file-extension=yaml
通過瀏覽器訪問http://localhost:8080/config,瀏覽器輸出如下
Hello Nacos Provider 我是配置服務A~
注意: Spring Boot 配置文件的加載順序,依次爲 bootstrap.properties
-> bootstrap.yml
-> application.properties
-> application.yml
,其中 bootstrap.properties 配置爲最高優先
4.Nacos多環境配置
概述
我們在做項目開發的時候,生產環境和測試環境的一些配置可能會不一樣,有時候一些功能也可能會不一樣,所以我們可能會在上線的時候手工修改這些配置信息。Spring 爲我們提供了 Spring Boot Profile 這個功能(Maven 也爲我們提供了 Maven Profile)。我們只需要在啓動的時候添加一個虛擬機參數,激活自己環境所要用的 Profile 就可以了。
操作起來很簡單,只需要爲不同的環境編寫專門的配置文件,如:application-dev.yml
、application-prod.yml
, 啓動項目時只需要增加一個命令參數 --spring.profiles.active=
環境配置即可
java -jar 1.0.0-SNAPSHOT.jar --spring.profiles.active=prod
什麼是 Nacos Config Profile
spring-cloud-starter-alibaba-nacos-config
在加載配置的時候,不僅僅加載了以 dataid 爲 ${spring.application.name}.${file-extension:properties}
爲前綴的基礎配置,還加載了 dataid 爲 ${spring.application.name}-${profile}.${file-extension:properties}
的基礎配置。在日常開發中如果遇到多套環境下的不同配置,可以通過 Spring 提供的 ${spring.profiles.active}
這個配置項來配置。
使用 Nacos Config Profile
我們以 service-provider
項目爲例,演示多環境配置效果,不要忘記依賴 Nacos Config Starter
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
使用控制檯發佈配置
注意: 控制檯發佈配置時不要加註釋,否則打成 Jar 包後運行會報無法解析配置文件的錯誤
通過瀏覽器訪問 http://localhost:8848/navcos,訪問 Nacos Server
- 發佈一個名爲
service-provider-config.yaml
的 測試環境 配置
spring:
application:
# 服務名
name: service-provider
cloud:
nacos:
discovery:
# 服務註冊中心
server-addr: 192.168.88.132:8848
server:
# 服務端口
port: 8070
management:
# 端點檢查(健康檢查)
endpoints:
web:
exposure:
include: "*"
- 發佈一個名爲
service-provider-config-prod.yaml
的 生產環境 配置
spring: application: # 服務名 name: service-provider cloud: nacos: discovery: # 服務註冊中心 server-addr: 192.168.141.132:8848server: # 修改了上面的端口號,區分配置的不同 port: 8071management: # 端點檢查(健康檢查) endpoints: web: exposure: include: "*"
修改客戶端配置
- 創建名爲
bootstrap.properties
的配置文件並刪除之前創建的application.yml
配置文件
spring.application.name=service-provider-config
spring.cloud.nacos.config.server-addr=192.168.88.132:8848
spring.cloud.nacos.config.file-extension=yaml
- 創建名爲
bootstrap-prod.properties
的配置文件
spring.profiles.active=prod
spring.application.name=service-provider-config
spring.cloud.nacos.config.server-addr=192.168.88.132:8848
spring.cloud.nacos.config.file-extension=yaml
測試多環境配置
此時我們有兩個配置文件,分別爲 bootstrap.properties
和 bootstrap-prod.properties
,我們需要指定啓動時加載哪一個配置文件
Run -> Edit Configurations -> Active profiles:
運行項目並觀察日誌
由上圖可知,我們成功加載了不同環境的配置