前言:您可以在本篇學習到以下知識點:
1)能夠理解微服務架構的特點
2)能夠理解服務發現的流程
3)能夠說出Nacos的功能
4)掌握Nacos的安裝方法
5)掌握RESTful服務發現開發方法
6)掌握Dubbo服務發現開發方法
7)理解Nacos服務發現的數據模型
8)能夠掌握Nacos配置管理方法
9)掌握Nacos擴展配置方法
1 理解服務發現
1.1 微服務架構
為適應企業的業務發展,提高軟件研發的生產力,降低軟件研發的成本,軟件架構也作了升級和優化,將一個獨立的系統拆分成若干小的服務,每個小服務運行在不同的進程中,服務與服務之間采用RESTful、RPC等協議傳輸數據,每個服務所擁有的功能具有獨立性強的特點,這樣的設計就實現了單個服務的高內聚,服務與服務之間的低耦合效果,這些小服務就是微服務,基于這種方法設計的系統架構即微服務架構。
特點:
1、服務層按業務拆分為一個一個的微服務。
2、微服務的職責單一。
3、微服務之間采用RESTful、RPC等輕量級協議傳輸。
4、有利于采用前后端分離架構。
1.2 理解服務發現
1.2.1 測試環境
在微服務架構中,整個系統會按職責能力劃分為多個服務,通過服務之間協作來實現業務目標。這樣在我們的代碼中免不了要進行服務間的遠程調用,服務的消費方要調用服務的生產方,為了完成一次請求,消費方需要知道服務生產方的網絡位置(IP地址和端口號)
通過Spring boot技術很容易實現
1、創建nacos-discovery父工程
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>
<groupId>com.itheima.nacos</groupId>
<artifactId>nacos‐discovery</artifactId>
<version>1.0‐SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2、Service B(服務生產者)
創建服務提供者 nacos-restful-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>nacos‐discovery</artifactId>
<groupId>com.itheima.nacos</groupId>
<version>1.0‐SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos‐restful‐provider</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐web</artifactId>
</dependency>
</dependencies>
</project>
Service B是服務的生產方,暴露/service服務地址,實現代碼如下:
1、創建Controller
package com.itheima.nacos.provider.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RestProviderController {
@GetMapping(value = "/service") //暴露服務
public String service(){
System.out.println("provider invoke");
return "provider invoke";
}
}
2、創建啟動類
@SpringBootApplication
public class SpringRestProviderBootstrap {
public static void main(String[] args) {
SpringApplication.run(SpringRestProviderBootstrap.class, args);
}
}
配置文件:
創建application.yml,內容如下:
server:
port:56010
3、Service A(服務消費者)
創建nacos-restful-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">
<parent>
<artifactId>nacos‐discovery</artifactId>
<groupId>com.itheima.nacos</groupId>
<version>1.0‐SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos‐restful‐consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐web</artifactId>
</dependency>
</dependencies>
</project>
實現代碼:
1、創建controller
package com.itheima.nacos.consumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class RestConsumerController {
@Value("${provider.address}")
private String providerAddress;
@GetMapping(value = "/service")
public String service(){
RestTemplate restTemplate = new RestTemplate();
//調用服務
String providerResult = restTemplate.getForObject("http://" + providerAddress +
"/service",String.class);
return "consumer invoke | " + providerResult;
}
}
2、創建啟動類
@SpringBootApplication
public class SpringRestConsumerBootstrap {
public static void main(String[] args) {
SpringApplication.run(SpringRestConsumerBootstrap.class, args);
}
}
配置文件:
創建application.yml,內容如下:
server.port = 56020
# 服務生產方地址
provider.address = 127.0.0.1:56010
訪問http://127.0.0.1:56020/service,輸出以下內容:
consumer invoke | provider invoke
1.2.2 服務發現流程
上邊的例子方案對于微服務應用而言行不通。首先,微服務可能是部署在云環境的,服務實例的網絡位置或許是動態分配的。另外,每一個服務一般會有多個實例來做負載均衡,由于宕機或升級,服務實例網絡地址會經常動態改變。再者,每一個服務也可能應對臨時訪問壓力增加新的服務節點。
基于以上的問題,服務之間如何相互發現?服務如何管理?這就是服務發現的問題了。
服務發現就是服務消費方通過服務發現中心智能發現服務提供方,從而進行遠程調用的過程。
上圖中服務實例本身并不記錄服務生產方的網絡地址,所有服務實例內部都會包含服務發現客戶端。
(1)在每個服務啟動時會向服務發現中心上報自己的網絡位置。這樣,在服務發現中心內部會形成一個服務注冊表,服務注冊表是服務發現的核心部分,是包含所有服務實例的網絡地址的數據庫。
(2)服務發現客戶端會定期從服務發現中心同步服務注冊表 ,并緩存在客戶端。
(3)當需要對某服務進行請求時,服務實例通過該注冊表,定位目標服務網絡地址。若目標服務存在多個網絡地址,則使用負載均衡算法從多個服務實例中選擇出一個,然后發出請求。
總結,在微服務環境中,由于服務運行實例的網絡地址是不斷動態變化的,服務實例數量的動態變化 ,因此無法使用固定的配置文件來記錄服務提供方的網絡地址,必須使用動態的服務發現機制用于實現微服務間的相互感知。
各服務實例會上報自己的網絡地址,這樣服務中心就形成了一個完整的服務注冊表,各服務實例會通過服務發現中心來獲取訪問目標服務的網絡地址,從而實現服務發現的機制。
2 Nacos 服務發現
2.1 Nacos簡介
2.1.1 服務發現產品對比
從上面對比可以了解到,Nacos作為服務發現中心,具備更多的功能支持項,且從長遠來看Nacos在以后的版本會支持SpringCLoud+Kubernetes的組合,填補 2 者的鴻溝,在兩套體系下可以采用同一套服務發現和配置管理的解決方案,這將大大的簡化使用和維護的成本。另外,Nacos 計劃實現 Service Mesh,也是未來微服務發展的趨勢。
2.1.2 Nacos簡介
Nacos是阿里的一個開源產品,它是針對微服務架構中的服務發現、配置管理、服務治理的綜合型解決方案。
2.1.3 Nacos特性
Nacos主要提供以下四大功能:
1. 服務發現與服務健康檢查
Nacos使服務更容易注冊,并通過DNS或HTTP接口發現其他服務,Nacos還提供服務的實時健康檢查,以防止向不健康的主機或服務實例發送請求。
2. 動態配置管理
動態配置服務允許您在所有環境中以集中和動態的方式管理所有服務的配置。Nacos消除了在更新配置時重新部署應用程序,這使配置的更改更加高效和靈活。
3. 動態DNS服務
Nacos提供基于DNS【域名系統(Domain Name System,縮寫:DNS)】 協議的服務發現能力,旨在支持異構語言的服務發現,支持將注冊在Nacos上的服務以域名的方式暴露端點,讓三方應用方便的查閱及發現。
4. 服務和元數據管理
Nacos 能讓您從微服務平臺建設的視角管理數據中心的所有服務及元數據,包括管理服務的描述、生命周期、服務的靜態依賴分析、服務的健康狀態、服務的流量管理、路由及安全策略。
2.2 安裝Nacos Server
2.2.1 預備環境準備
Nacos 依賴 Java 環境來運行。如果您是從代碼開始構建并運行Nacos,還需要為此配置 Maven環境,請確保是在
以下版本環境中安裝使用:
1. 64 bit OS,支持 Linux/Unix/Mac/Windows,推薦選用 Linux/Unix/Mac。
2. 64 bit JDK 1.8+;下載 & 配置。
3. Maven 3.2.x+;下載 & 配置。
2.2.2 下載源碼或者安裝包
你可以通過源碼和發行包兩種方式來獲取 Nacos。
從 Github 上下載源碼方式
git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn ‐Prelease‐nacos clean install ‐U
ls ‐al distribution/target/
// change the $version to your actual path
cd distribution/target/nacos‐server‐$version/nacos/bin
下載編譯后壓縮包方式
您可以從 最新穩定版本 下載 nacos-server-$version.zip 包,本教程使用nacos-server-1.1.3版本。
下載地址:https://github.com/alibaba/nacos/releases
下載后解壓:unzip nacos‐server‐$version.zip 或者 tar ‐xvf nacos‐server‐$version.tar.gz cd nacos/bin
2.2.3 啟動服務器
nacos的默認端口是8848,需要保證8848默認端口沒有被其他進程占用。
進入安裝程序的bin目錄:
Linux/Unix/Mac啟動方式:
啟動命令(standalone代表著單機模式運行,非集群模式):
sh startup.sh -m standalone
如果您使用的是ubuntu系統,或者運行腳本報錯提示[[符號找不到,可嘗試如下運行:
bash startup.sh -m standalone
Windows啟動方式:
啟動命令:
cmd startup.cmd
或者雙擊startup.cmd運行文件。
啟動成功,可通過瀏覽器訪問 http://127.0.0.1:8848/nacos ,打開如下nacos控制臺登錄頁面:
使用默認用戶名:nacos,默認密碼:nacos 登錄即可打開主頁面。
2.2.4 外部mysql數據庫支持
單機模式時nacos默認使用嵌入式數據庫實現數據的存儲,若想使用外部mysql存儲nacos數據,需要進行以下步驟:
1.安裝數據庫,版本要求:5.6.5+ ,mysql 8 以下
2.初始化mysql數據庫,新建數據庫nacos_confifig,數據庫初始化文件:${安裝路徑下}/conf/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_config?
characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest
db.password=youdontknow
2.3 RESTful服務發現
2.3.1 測試環境
本測試環境采用阿里開源的Spring Cloud Alibaba微服務開發框架,Spring Cloud Alibaba是阿里巴巴公司基于Spring Cloud標準實現一套微服務開發框架集合
通過Spring Cloud Alibaba實現解決:
1、服務發現客戶端從服務發現中心獲取服務列表
2、服務消費方通過負載均衡獲取服務地址
#在nacos-discovery父工程中添加依賴管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐alibaba‐dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
分別在服務提供及服務消費工程中添加依賴,此依賴的作用是服務發現
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐alibaba‐nacos‐discovery</artifactId>
</dependency>
2.3.2 服務注冊
在服務提供工程中配置nacos服務發現相關的配置:
服務提供:
spring:
application:
name: nacos‐restful‐provider
cloud:
nacos:
discovery:
server‐addr: 127.0.0.1:8848
啟動nacos
啟動服務提供
觀察nacos服務列表,nacos-restful-provider注冊成功
服務名稱:每個服務在服務注冊中心的標識,相當于Java中的類名。
服務實例:網絡中提供服務的實例,具有IP和端口,相當于Java中的對象,一個實例即為運行在服務器上的一個進程。
2.3.3 服務發現
在服務消費工程中配置nacos服務發現相關的配置:
服務消費:
spring:
application:
name: nacos‐restful‐consumer
cloud:
nacos:
discovery:
server‐addr: 127.0.0.1:8848
修改Controller中遠程調用的代碼:
//服務id即注冊中心的中的服務名
private String serviceId="nacos‐restful‐provider";
@Autowired
LoadBalancerClient loadBalancerClient;
@GetMapping(value = "/service")
public String service(){
RestTemplate restTemplate = new RestTemplate();
//調用服務
// String providerResult = restTemplate.getForObject("http://" + providerAddress +
"/service",String.class);
ServiceInstance serviceInstance = loadBalancerClient.choose(serviceId);
URI uri = serviceInstance.getUri();
String providerResult = restTemplate.getForObject(uri+"/service",String.class);
return "consumer invoke | " + providerResult;
}
2.3.4 負載均衡
在RESTful服務發現的流程中,ServiceA通過負載均衡調用ServiceB,下邊來了解一下負載均衡:
負載均衡就是將用戶請求(流量)通過一定的策略,分攤在多個服務實例上執行,它是系統處理高并發、緩解網絡壓力和進行服務端擴容的重要手段之一。它分為服務端負載均衡和客戶端負載均衡。
服務器端負載均衡:當客戶端請求來臨時,負載均衡服務器按照某種配置好的規則(負載均衡算法)從可用服務實例清單中選取其一去處理客戶端的請求。這就是服務端負載均衡。
客戶端服務負載均衡:上邊使用的LoadBalancerClient就是一個客戶端負載均衡器,具體使用的是Ribbon客戶端負載均衡器。Ribbon在發送請求前通過負載均衡算法選擇一個服務實例,然后進行訪問,這是客戶端負載均衡。即在客戶端就進行負載均衡的分配。Ribbon核心組件IRule是負載均衡策略接口,它有如下實現,大家僅做了解:RoundRobinRule(默認):輪詢,即按一定的順序輪換獲取實例的地址。RandomRule:隨機,即以隨機的方式獲取實例的地址。
Ribbon核心組件IRule是負載均衡策略接口,它有如下實現,大家僅做了解:
RoundRobinRule(默認):輪詢,即按一定的順序輪換獲取實例的地址。
RandomRule:隨機,即以隨機的方式獲取實例的地址。
可通過下面方式在服務消費方的 配置文件中修改默認的負載均衡策略:
nacos‐restful‐provider:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
2.3.5 小結
服務注冊與發現流程:
1、服務提供方將自己注冊到服務注冊中心
2、服務消費方從注冊中心獲取服務地址
3、通過客戶端負載均衡器進行遠程調用
2.4 Dubbo服務發現
Dubbo是阿里巴巴公司開源的RPC框架,在國內有著非常大的用戶群體,但是其微服務開發組件相對Spring Cloud來說并不那么完善。
Spring Cloud Alibaba微服務開發框架集成了Dubbo,可實現微服務對外暴露Dubbo協議的接口,Dubbo協議相比RESTful協議速度更快。
RPC:RPC是遠程過程調用(Remote Procedure Call)的縮寫形式,調用RPC遠程方法就像調用本地方法一樣
交互流程:
1、網關負責客戶端請求的統一入口,路由轉發,前端通過網關請求后端服務。
2、網關收到前端請求,轉發請求給應用。
3、應用接收前端請求,調用微服務進行業務邏輯處理
4、微服務為應用提供業務邏輯處理的支撐,為應用提供Dubbo協議接口
優勢分析:
此架構同時提供RESTful和Dubbo接口服務,應用層對前端提供RESTful接口,RESTful是互聯網通用的輕量級交互
協議,方便前端接入系統;微服務層向應用層提供Dubbo接口,Dubbo接口基于RPC通信協議速度更快。
本架構采用阿里開源的Nacos,集服務發現和配置中心于一身,支持RESTful及Dubbo服務的注冊。
2.4.2 測試環境
父工程:仍然使用nacos-dicovery。
application1:使用nacos-restful-consumer。
service1微服務:需要新建
service2微服務:需要新建
api網關:后邊的課程內容講解。
2.4.3 service2微服務
service2對外暴露dubbo協議的接口,考慮遠程接口可能 會被其它多個服務調用,這里將service2的接口單獨抽取
出api工程,service2微服務工程的結構如下:
service2-api:存放接口,獨立成一個工程方便被其它服務工程依賴。
service2-server:存放接口實現,即dubbo服務的實現部分。
2.4.3.1 定義service2-api
1、創建service2工程
<?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>nacos‐discovery</artifactId>
<groupId>com.itheima.nacos</groupId>
<version>1.0‐SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos‐dubbo‐service2</artifactId>
<packaging>pom</packaging>
</project>
2、創建service2-api工程
<?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>nacos‐dubbo‐service1</artifactId>
<groupId>com.itheima.nacos</groupId>
<version>1.0‐SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service2‐api</artifactId>
3、定義接口
package com.itheima.microservice.service2.api;
public interface Service2Api {
public String dubboService2();
}
2.4.3.2 定義service2-server
1、創建service2-server工程
<?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>nacos‐dubbo‐service1</artifactId>
<groupId>com.itheima.nacos</groupId>
<version>1.0‐SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service2‐server</artifactId>
<dependencies>
<dependency>
<groupId>com.itheima.nacos</groupId>
<artifactId>service2‐api</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐alibaba‐nacos‐discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐dubbo</artifactId>
</dependency>
</dependencies>
</project>
2、定義接口實現
注意:使用@org.apache.dubbo.confifig.annotation.Service標記dubbo服務
package com.itheima.microservice.service2.service;
import com.itheima.microservice.service2.api.Service2Api;
@org.apache.dubbo.config.annotation.Service
public class Service2ApiImpl implements Service2Api {
public String dubboService2() {
return "dubboService2";
}
}
3、定義啟動類
package com.itheima.microservice.service2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Service2Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Service2Bootstrap.class, args);
}
}
4、定義配置文件bootstrap.yml
server:
port: 56040 #啟動端口 命令行注入
spring:
application:
name: dubbo‐service2
main:
allow‐bean‐definition‐overriding: true # Spring Boot 2.1 需要設定
cloud:
nacos:
discovery:
server‐addr: 127.0.0.1:8848
dubbo:
scan:
# dubbo 服務掃描基準包
base‐packages: com.itheima.microservice.service2.service
protocol:
# dubbo 協議
name: dubbo
# dubbo 協議端口
port: 20891
registry:
address: nacos://127.0.0.1:8848
application:
qos‐enable: false #dubbo運維服務是否開啟
consumer:
check: false #啟動時就否檢查依賴的服務
5、啟動service2-server
啟動成功觀察nacos的服務列表
2.4.4 application1調用service2
根據dubbo服務的架構圖,本章節將nacos-restful-consumer作為application1,實現application1調用
service2。
2.4.4.1 引用service2
在nacos-restful-consumer工程中引用service2依賴
在pom.xml中引入service2-api的依賴
<dependency>
<groupId>com.itheima.nacos</groupId>
<artifactId>service2‐api</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>
引入 spring-cloud-starter-dubbo依賴,它會根據接口生成代理對象
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐dubbo</artifactId>
</dependency>
2.4.4.2 實現遠程調用
修改nacos-restful-consumer工程的RestConsumerController:
@org.apache.dubbo.config.annotation.Reference
private Service2Api service2Api;
@GetMapping(value = "/service2")
public String service2(){
//遠程調用service2
String providerResult = service2Api.dubboService2();
return "consumer dubbo invoke | " + providerResult;
}
注意:這里的 @Reference 注解是 org.apache.dubbo.config.annotation.Reference
測試請求:http://127.0.0.1:56020/service2
顯示:consumer dubbo invoke | dubboService2 表明service2調用成功。
2.4.5 service1微服務
service1采用和service2相同的工程結構。
本節實現service1對外暴露dubbo接口,并用實現service1調用service2。
2.4.5.1 定義service1-api
1、創建service1工程
<?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>nacos‐discovery</artifactId>
<groupId>com.itheima.nacos</groupId>
<version>1.0‐SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos‐dubbo‐service1</artifactId>
<packaging>pom</packaging>
</project>
2、創建service1-api工程
<?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>nacos‐dubbo‐service1</artifactId>
<groupId>com.itheima.nacos</groupId>
<version>1.0‐SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service1‐api</artifactId>
</project>
3、定義接口
package com.itheima.microservice.service1.api;
public interface Service1Api {
public String dubboService1();
}
2.4.5.2 定義service1-server
1、創建service1-server工程
由于實現service1調用service2,這里需要引入 service2依賴。
<?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>nacos‐dubbo‐service1</artifactId>
<groupId>com.itheima.nacos</groupId>
<version>1.0‐SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service1‐server</artifactId>
<dependencies>
<dependency>
<groupId>com.itheima.nacos</groupId>
<artifactId>service1‐api</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.itheima.nacos</groupId>
<artifactId>service2‐api</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐alibaba‐nacos‐discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐dubbo</artifactId>
</dependency>
</dependencies>
</project>
2、定義接口實現
package com.itheima.microservice.service1.service;
import com.itheima.microservice.service1.api.Service1Api;
import com.itheima.microservice.service2.api.Service2Api;
import org.apache.dubbo.config.annotation.Reference;
@org.apache.dubbo.config.annotation.Service
public class Service1ApiImpl implements Service1Api {
@Reference
Service2Api service2Api;
public String dubboService1() {
String s = service2Api.dubboService2();
return "dubboService1|"+s;
}
}
3、定義啟動類
package com.itheima.microservice.service1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Service1Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Service1Bootstrap.class, args);
}
}
4、定義配置文件bootstrap.yml
server:
port: 56030 #啟動端口 命令行注入
spring:
application:
name: dubbo‐service1
main:
allow‐bean‐definition‐overriding: true # Spring Boot 2.1 需要設定
cloud:
nacos:
discovery:
server‐addr: 127.0.0.1:8848
dubbo:
scan:
# dubbo 服務掃描基準包
base‐packages: com.itheima.microservice.service1.service
protocol:
# dubbo 協議
name: dubbo
# dubbo 協議端口
port: 20881
registry:
address: nacos://127.0.0.1:8848
application:
qos‐enable: false #dubbo運維服務是否開啟
consumer:
check: false #啟動時就否檢查依賴的服務
5、啟動service1-server
啟動成功觀察nacos的服務列表
2.4.5.3 application1調用service1
參考 application1調用service2的方法實現。
1、在application1引入 service1-api的依賴
略
2、在application1的controller中調用service1接口
@Reference
private Service1Api service1Api;
@GetMapping(value = "/service3")
public String service1(){
String providerResult = service1Api.dubboService1();
return "consumer dubbo invoke | " + providerResult;
}
3、測試,請求http://127.0.0.1:56020/service3
顯示 :consumer dubbo invoke | dubboService1|dubboService2,表明調用service1成功,service1調用
service2成功。
2.5 服務發現數據模型
2.5.1Namespace 隔離設計
命名空間(Namespace)用于進行租戶粒度的隔離,Namespace 的常用場景之一是不同環境的隔離,例如開發測試
環境和生產環境的資源(如配置、服務)隔離等。
從一個租戶(用戶)的角度來看,如果有多套不同的環境,那么這個時候可以根據指定的環境來創建不同的
namespce,以此來實現多環境的隔離。例如,你可能有開發,測試和生產三個不同的環境,那么使用一套
nacos 集群可以分別建以下三個不同的 namespace
2.5.2 命名空間管理
前面已經介紹過,命名空間(Namespace)是用于隔離多個環境的(如開發、測試、生產),而每個應用在不同環
境的同一個配置(如數據庫數據源)的值是不一樣的。因此,我們應針對企業項目實際研發流程、環境進行規劃。
如某軟件公司擁有開發、測試、生產三套環境,那么我們應該針對這三個環境分別建立三個namespace。
Nacos在經過阿里內部多年生產經驗后提煉出的數據模型,則是一種服務-集群-實例的三層模型,這樣基本可以滿
足服務在所有場景下的數據存儲和管理。
例子如下:
指定namespace的id:a1f8e863-3117-48c4-9dd3-e9ddc2af90a8(注意根據自己環境設置namespace的id)
指定集群名稱:DEFAULT表示默認集群,可不填寫
spring:
application:
name: transaction‐service
cloud:
nacos:
discovery:
server‐addr: 127.0.0.1:7283 # 注冊中心地址
namespace: a1f8e863‐3117‐48c4‐9dd3‐e9ddc2af90a8 # 開發環境
cluster‐name: DEFAULT # 默認集群,可不填寫
3 Nacos配置管理
3.1 理解配置中心
3.1.1 什么是配置
應用程序在啟動和運行的時候往往需要讀取一些配置信息,配置基本上伴隨著應用程序的整個生命周期,比如:數
據庫連接參數、啟動參數等。
3.1.2 什么是配置中心
在微服務架構中,當系統從一個單體應用,被拆分成分布式系統上一個個服務節點后,配置文件也必須跟著遷移
(分割),這樣配置就分散了,不僅如此,分散中還包含著冗余,總得來說,配置中心就是一種統一管理各種應用配置的基礎服務組件。
Nacos的一大優勢是整合了注冊中心、配置中心功能,部署和操作相比Apollo都要直觀簡單,因此它簡化了架構復雜度,并減輕運維及部署工作。
3.2 Nacos配置管理
3.2.1 發布配置
首先在nacos發布配置,nacos-restful-consumer服務從nacos讀取配置。
瀏覽器訪問 http://127.0.0.1:8848/nacos ,打開nacos控制臺,并點擊菜單配置管理->配置列表:
在Nacos添加如下的配置:
nacos-restful-consumer:
Namespace: public
Data ID: nacos‐restful‐consumer.yaml
Group : DEFAULT_GROUP
配置格式: YAML
配置內容: common:
name: application1 config
3.2.2 獲取配置
要想從配置中心獲取配置添加nacos-confifig的依賴:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐alibaba‐nacos‐config</artifactId>
</dependency>
在bootstrap.yml添加配置:
spring:
cloud:
nacos:
config:
server‐addr: 127.0.0.1:8848 # 配置中心地址
file‐extension: yaml
group: DEFAULT_GROUP
注意:要使用配置中心就要在bootstrap.yml中來配置,bootstrap.yml配置文件的加載順序要比application.yml要
優先。
在nacos-restful-consumer工程的controller中增加獲取配置的web訪問端點/configs,通過標準的spring @Value
方式。
@Value("${common.name}")
private String common_name;
@GetMapping(value = "/configs")
public String getvalue(){
return common_name;
}
基于上面的例子,若要實現配置的動態更新,只需要進行如下改造:
// 注入配置文件上下文
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping(value = "/configs")
public String getConfigs(){
return applicationContext.getEnvironment().getProperty("common.name");
}
我們通過nacos控制臺更新common.name的配置值,再次訪問web端點/confifigs,發現應用程序能夠獲取到最新
的配置值,說明spring-cloud-starter-alibaba-nacos-confifig 支持配置的動態更新。
3.2.3 配置管理模型
對于Nacos配置管理,通過Namespace、group、Data ID能夠定位到一個配置集。
Nacos抽象定義了Namespace、Group、Data ID的概念,具體這幾個概念代表什么,取決于我們把它們看成什
么,這里推薦給大家一種用法,如下圖:
Namespace:代表不同環境,如開發、測試、生產環境。
Group:代表某項目,如XX醫療項目、XX電商項目
DataId:每個項目下往往有若干個工程,每個配置集(DataId)是一個工程的主配置文件
獲取某配置集的代碼:
獲取配置集需要指定:
1、nacos服務地址,必須指定
2、namespace,如不指定默認public
在confifig中指定namespace,例子如下:
config:
server‐addr: 127.0.0.1:8848 # 配置中心地址
file‐extension: yaml
namespace: a1f8e863‐3117‐48c4‐9dd3‐e9ddc2af90a8 # 開發環境
group: DEFAULT_GROUP # xx業務組
3、group,如不指定默認 DEFAULT_GROUP
見上邊第2點的例子。
4、dataId,必須指定,名稱為應用名稱+配置文件擴展名
3.3 自定義擴展的 Data Id 配置
3.3.1 ext-confifig擴展配置
Spring Cloud Alibaba Nacos Confifig可支持自定義 Data Id 的配置。 一個完整的配置案例如下所示:
spring:
application:
name: service2
cloud:
nacos:
config:
server‐addr: 127.0.0.1:8848 # 配置中心地址
file‐extension: yaml
# namespace: a1f8e863‐3117‐48c4‐9dd3‐e9ddc2af90a8 # 開發環境
group: DEFAULT_GROUP
# config external configuration
# 1、Data Id group:組名,refresh:動態刷新
ext‐config[0]:
data‐id: ext‐config‐common01.yaml
group: COMMON_GROUP
refresh: true
ext‐config[1]:
data‐id: ext‐config‐common02.yaml
group: COMMON_GROUP
refresh: true
可以看到:
通過 spring.cloud.nacos.config.ext-config[n].data-id 的配置方式來支持多個 Data Id 的配置。
通過 spring.cloud.nacos.config.ext-config[n].group 的配置方式自定義 Data Id 所在的組,不明確配置
的話,默認是 DEFAULT_GROUP。
@GetMapping(value = "/configs")
public String getvalue(){
String name = applicationContext.getEnvironment().getProperty("common.name");
String address = applicationContext.getEnvironment().getProperty("common.addr");
return name+address;
}
重啟nacos-restful-consumer工程
訪問:http://127.0.0.1:56020/confifigs
通過測試發現:
擴展配置優先級是 spring.cloud.nacos.config.ext-config[n].data-id 其中 n 的值越大,優先級越高。
通過內部相關規則(應用名、擴展名 )自動生成相關的 Data Id 配置的優先級最大
3.3.2 案例
案例需求如下:
1、抽取servlet公用的配置到獨立的配置文件,配置文件內容如下:
#HTTP格式配置
spring:
http:
encoding:
charset: UTF‐8
force: true
enabled: true
messages:
encoding: UTF‐8
#tomcat頭信息和訪問路徑配置
server:
tomcat:
remote_ip_header: x‐forwarded‐for
protocol_header: x‐forwarded‐proto
servlet:
context‐path: /a
use‐forward‐headers: true
發布配置,重啟nacos-restful-consumer
訪問http://127.0.0.1:56020/a/confifigs驗證配置是否生效
4 總結
Nacos用來干什么?
Nacos是阿里巴巴公司開源的項目,它用來實現配置中心和服務注冊中心。
什么是服務發現?
在微服務架構中一個業務流程需要多個微服務通過網絡接口調用完成業務處理,服務消費方從服務注冊中心獲取服
務提供方的地址,從而進行遠程調用,這個過程叫做服務發現。
服務發現的流程是什么?
1、服務發現的客戶端從服務注冊中心獲取服務列表
2、服務消費方通過客戶端負載均衡獲取服務實例地址,進行遠程調用。
什么是配置中心?
在微服務架構中為了統一管理各各微服務的配置信息專門設置配置中心,配置中心就是一種統一管理各種應用配置
的基礎服務組件。
配置中心的應用流程是什么?
1、發布配置,將配置信息發布到配置中心。
2、獲取配置,配置中心客戶端得到配置中心的通知,從配置中心獲取配置。
Spring Cloud是什么?
Spring Cloud是一套微服務開發框架集合,包括微服務開發的方方頁面,Spring Cloud是一套微服務開發的標準,
集成了很多優秀的開源框架,比如有名的Netflflix公司的眾多項目。
Spring Cloud Alibaba是什么?
Spring Cloud Alibaba是阿里巴巴公司基于Spring Cloud標準實現一套微服務開發框架集合,它和Netflflix一樣都是
Spring Cloud微服務開發實現方案。
Dubbo服務開發流程是什么?
1、定義api工程。
方便其它服務原來api工程,遠程調用dubbo服務。
2、定義api實現工程。
service實現類使用 @org.apache.dubbo.confifig.annotation.Service注解標記為dubbo服務。
3、服務消費方開發
引入api工程依賴
使用org.apache.dubbo.confifig.annotation.Reference注解注入service,發起遠程調用