您好,登錄后才能下訂單哦!
為了實(shí)現(xiàn)多個(gè)微服務(wù)之間的調(diào)用,我們除了需要Feign這種調(diào)用組件外還得依賴服務(wù)發(fā)現(xiàn)組件。主要的原因是每個(gè)微服務(wù)所在的機(jī)器ip并非總是固定的,并且每個(gè)微服務(wù)都可能部署多個(gè)實(shí)例在不同的機(jī)器上,所以我們不能把依賴的微服務(wù)ip地址寫在代碼或配置文件里,我們需要有個(gè)組件去動(dòng)態(tài)的管理,這就是為什么微服務(wù)架構(gòu)里服務(wù)發(fā)現(xiàn)功能是必須的。
那么服務(wù)發(fā)現(xiàn)組件是怎么實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)的呢?我們以大家比較熟悉的MySQL來做類比,通過MySQL簡(jiǎn)單說明一下服務(wù)發(fā)現(xiàn)機(jī)制的實(shí)現(xiàn)。如下圖:
簡(jiǎn)單說明一下什么是服務(wù)提供者與服務(wù)消費(fèi)者:
當(dāng)微服務(wù)啟動(dòng)的時(shí)候會(huì)向服務(wù)發(fā)現(xiàn)組件注冊(cè)自身信息,在上圖中就類似于向MySQL發(fā)送一條insert語(yǔ)句,將服務(wù)的元數(shù)據(jù)如服務(wù)名稱、ip地址及服務(wù)狀態(tài)等信息插入到MySQL中,如上圖的registry表數(shù)據(jù)所示,這個(gè)過程稱之為服務(wù)注冊(cè),所以服務(wù)發(fā)現(xiàn)組件內(nèi)部會(huì)都維護(hù)類似于這樣的一張注冊(cè)表。
微服務(wù)在注冊(cè)完成后,會(huì)讀取服務(wù)發(fā)現(xiàn)組件中保存的其他微服務(wù)的元數(shù)據(jù)并緩存一份到本地,就類似于向MySQL發(fā)送一條select all語(yǔ)句。這樣在調(diào)用其他服務(wù)的時(shí)候,就不需要每次都去服務(wù)發(fā)現(xiàn)組件上查詢,而是從本地緩存去查找調(diào)用地址,這樣可以減輕服務(wù)發(fā)現(xiàn)組件的壓力。所以上圖中的調(diào)用箭頭并沒有指向服務(wù)發(fā)現(xiàn)組件,而是直接指向服務(wù)提供者。這樣的好處是哪怕是服務(wù)發(fā)現(xiàn)組件掛掉了,還能從本地緩存中獲取其他微服務(wù)的調(diào)用地址。到這一步微服務(wù)之間就可以互相發(fā)現(xiàn)了,即完成基本的服務(wù)發(fā)現(xiàn)
但微服務(wù)有可能會(huì)掛掉或下線,此時(shí)其他服務(wù)不應(yīng)該去發(fā)現(xiàn)一個(gè)不存在的服務(wù)。所以每個(gè)服務(wù)啟動(dòng)且向服務(wù)發(fā)現(xiàn)組件注冊(cè)完成之后,都會(huì)通過心跳機(jī)制告知存活狀態(tài)。上圖中用last_heartbeat字段表示,若某個(gè)服務(wù)在超過一定的時(shí)間都沒有發(fā)送心跳包的話,就會(huì)被服務(wù)發(fā)現(xiàn)組件檢測(cè)到,此時(shí)就會(huì)刪除注冊(cè)表里該服務(wù)的注冊(cè)信息,并通知其他服務(wù)更新本地緩存(若有新注冊(cè)的服務(wù)也會(huì)通知其他服務(wù)更新本地緩存)。
關(guān)于什么是Nacos,官方文檔已經(jīng)描述得很詳細(xì)了,Nacos官方文檔地址如下:
https://nacos.io/zh-cn/docs/what-is-nacos.html
所以這里只是簡(jiǎn)單概述一下,Nacos與Eureka一樣,是服務(wù)發(fā)現(xiàn)組件,同時(shí)也是配置中心。Nacos解決了兩個(gè)問題,一是服務(wù)A如何找到服務(wù)B;二是管理微服務(wù)的配置,讓一個(gè)微服務(wù)的所有實(shí)例的配置都統(tǒng)一,并且可以實(shí)現(xiàn)配置修改后自動(dòng)刷新等。
理論介紹也說得差不多了,本小節(jié)我們來動(dòng)手搭建一個(gè)Nacos Server。過程很簡(jiǎn)單首先需要下載一個(gè)Nacos,下載地址如下:
https://github.com/alibaba/nacos/releases
然后我們需要選擇一個(gè)合適的版本下載,即Nacos Server版本應(yīng)盡量與Client端的版本對(duì)應(yīng)。至于Client的版本我們可以到工程的pom.xml文件中找到Spring Cloud Alibaba的依賴管理項(xiàng)點(diǎn)擊進(jìn)去即可查看到:
如下可以看到Nacos Client的版本為1.0.0,所以與之對(duì)應(yīng)選擇1.0.0版本的Nacos Server進(jìn)行下載:
注:我這里使用的Spring Cloud版本是Greenwich.SR1,Spring Cloud Alibaba的版本是0.9.0.RELEASE
由于不是生產(chǎn)環(huán)境所用,其實(shí)也無需嚴(yán)格選擇對(duì)應(yīng)的版本,只要能用就可以了,所以我這里選擇下載最新的1.1.0版本(經(jīng)過測(cè)試可用):
下載并解壓后進(jìn)入bin目錄,雙擊startup.cmd,或在命令行中輸入cmd startup.cmd即可運(yùn)行Nacos Server:
啟動(dòng)成功:
使用瀏覽器訪問localhost:8848
進(jìn)入Nacos Server的管理頁(yè)面,此時(shí)需要輸入賬戶密碼,默認(rèn)的賬戶密碼都是nacos:
登錄成功后,頁(yè)面如下:
該管理頁(yè)面支持中英文,可在右上角點(diǎn)擊切換:
官方文檔如下:
https://nacos.io/zh-cn/docs/quick-start.html
在上一小節(jié)中,我們已經(jīng)完成了Nacos Server的搭建,而這一小節(jié)將演示如何將微服務(wù)注冊(cè)到Nacos。我現(xiàn)在有一個(gè)用戶中心微服務(wù),其pom.xml文件如下,包含了Spring Cloud Alibaba及Nacos Client依賴,Spring Boot版本為2.1.6.RELEASE:
<dependencies>
...
<!-- Nacos Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!--整合Spring Cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--整合Spring Cloud Alibaba-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.9.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在配置文件中配置一下nacos server的地址及端口:
spring:
cloud:
nacos:
discovery:
# 指定nacos server的地址
server-addr: 127.0.0.1:8848
application:
# 服務(wù)名稱,必須的配置項(xiàng),否則不會(huì)向nacos注冊(cè)
name: user-center
...
配置完成后啟動(dòng)項(xiàng)目,然后到nacos server的管理頁(yè)面的服務(wù)列表上查看是否注冊(cè)成功,注冊(cè)成功的話會(huì)顯示在服務(wù)列表里,如下:
點(diǎn)擊詳情可以看到詳細(xì)信息:
經(jīng)過以上這幾個(gè)步驟,就可以非常簡(jiǎn)單地整合Nacos Client,并將微服務(wù)注冊(cè)到Nacos Server上。通過同樣的步驟,我將另一個(gè)內(nèi)容中心微服務(wù)也注冊(cè)到Nacos Server上。我們來寫一個(gè)簡(jiǎn)單的測(cè)試用例,看看在內(nèi)容中心上是否能發(fā)現(xiàn)用戶中心,代碼如下:
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class DiscoveryClientTests {
@Autowired
private DiscoveryClient discoveryClient;
/**
* 測(cè)試服務(wù)發(fā)現(xiàn),證明內(nèi)容中心能找到用戶中心
*/
@Test
public void getServiceInstancesTest(){
// 獲取用戶中心微服務(wù)的所有實(shí)例信息
List<ServiceInstance> instances = discoveryClient.getInstances("user-center");
// 以json格式打印出來
log.info(JsonUtil.obj2JsonPretty(instances));
}
}
控制臺(tái)輸出的json信息如下,證明通過服務(wù)發(fā)現(xiàn)組件能讓內(nèi)容中心總是能找到用戶中心:
[ {
"serviceId" : "user-center",
"host" : "192.168.190.1",
"port" : 8080,
"secure" : false,
"metadata" : {
"nacos.instanceId" : "192.168.190.1#8080#DEFAULT#DEFAULT_GROUP@@user-center",
"nacos.weight" : "1.0",
"nacos.cluster" : "DEFAULT",
"nacos.healthy" : "true",
"preserved.register.source" : "SPRING_CLOUD"
},
"uri" : "http://192.168.190.1:8080",
"scheme" : null,
"instanceId" : null
} ]
下圖整理了Nacos服務(wù)發(fā)現(xiàn)的領(lǐng)域模型,我們將圍繞該圖進(jìn)行介紹:
1、上圖最外層的是Namespace,對(duì)應(yīng)管理界面的命名空間,如下:
Namespace主要用作隔離,默認(rèn)為public,例如我們有三個(gè)環(huán)境:開發(fā)、測(cè)試及生產(chǎn)環(huán)境,那么就可以創(chuàng)建三個(gè)Namespace,不同的Namespace之間是互相隔離的。
舉個(gè)例子,我們可以來創(chuàng)建一個(gè)開發(fā)環(huán)境專用的命名空間:
創(chuàng)建完成后可以看到每個(gè)命名空間都會(huì)有自己的唯一命名空間id:
那么微服務(wù)要如何注冊(cè)到指定的命名空間呢?很簡(jiǎn)單,在配置文件中通過namespace配置項(xiàng)指定即可:
spring:
cloud:
nacos:
discovery:
# 指定nacos server的地址
server-addr: 127.0.0.1:8848
# 配置命名空間
namespace: 4a557407-c2c8-4524-97a0-17aa3c836407
...
配置完成后重啟項(xiàng)目,此時(shí)該服務(wù)不再是注冊(cè)到之前的public命名空間,而是注冊(cè)到我們剛剛創(chuàng)建的dev命名空間,此時(shí)在dev下的微服務(wù)是看不到public下的微服務(wù)的,即實(shí)現(xiàn)了環(huán)境隔離了:
2、在Namespace之下是Group服務(wù)分組,默認(rèn)的Group是DEFAULT_GROUP。我們可以在服務(wù)列表中看到:
Group可以將不同的微服務(wù)劃分到同一個(gè)分組里,Group可以讓我們方便去分組管理微服務(wù)。但需要注意的是,在目前的Spring Cloud Alibaba版本,并沒有用上這個(gè)Group,應(yīng)該會(huì)在未來的版本上支持。
3、而Group下面是Service,Service既是微服務(wù),例如用戶微服務(wù)、訂單微服務(wù)等。每個(gè)Service可以包含多個(gè)Cluster(集群),Cluster是對(duì)指定微服務(wù)的一個(gè)虛擬劃分,默認(rèn)為DEFAULT。比方說公司內(nèi)有北京機(jī)房、上海機(jī)房的服務(wù)器,那么為了異地容災(zāi),用戶中心微服務(wù)就可能會(huì)被同時(shí)部署在北京機(jī)房和上海機(jī)房。這時(shí)候我們就可以為北京機(jī)房的用戶中心微服務(wù)實(shí)例劃分到一個(gè)集群里并且起一個(gè)集群名稱,而上海機(jī)房的用戶中心微服務(wù)實(shí)例同理。將微服務(wù)實(shí)例劃分到一個(gè)集群后,我們還可以實(shí)現(xiàn)類似于讓上海機(jī)房里的微服務(wù)盡量調(diào)用同機(jī)房?jī)?nèi)的其他微服務(wù),這樣在容災(zāi)的同時(shí)還可以提升性能。
關(guān)于集群我們可以直接在配置文件中配置,而不用像命名空間那樣需要提前創(chuàng)建,如下:
spring:
cloud:
nacos:
discovery:
# 指定nacos server的地址
server-addr: 127.0.0.1:8848
# 配置集群名稱,名稱可以任意
cluster-name: BJ
...
配置完成后重啟項(xiàng)目,此時(shí)可以看到該微服務(wù)實(shí)例處于BJ集群下,而不是處于之前默認(rèn)的DEFAULT集群下:
4、Cluster里是Instance,即上面所提到的微服務(wù)實(shí)例
關(guān)于這些概念的官方文檔地址如下:
https://nacos.io/zh-cn/docs/concepts.html
什么是Nacos元數(shù)據(jù),官方文檔描述如下:
Nacos數(shù)據(jù)(如配置和服務(wù))描述信息,如服務(wù)版本、權(quán)重、容災(zāi)策略、負(fù)載均衡策略、鑒權(quán)配置、各種自定義標(biāo)簽 (label),從作用范圍來看,分為服務(wù)級(jí)別的元信息、集群的元信息及實(shí)例的元信息。
- 服務(wù)級(jí)別的元信息在服務(wù)詳情中展示
- 集群的元信息在集群配置中展示
- 實(shí)例的元信息在集群實(shí)例表內(nèi)展示
元數(shù)據(jù)作用:
配置元數(shù)據(jù)的兩種方式:
在Nacos Server的管理頁(yè)面設(shè)置;以服務(wù)的元數(shù)據(jù)示例,在服務(wù)詳情頁(yè)面點(diǎn)擊編輯服務(wù)后,在元數(shù)據(jù)這欄輸入json格式的元數(shù)據(jù)即可:
spring:
cloud:
nacos:
discovery:
# 指定nacos server的地址
server-addr: 127.0.0.1:8848
# 這種方式配置的是實(shí)例級(jí)別的元數(shù)據(jù)
metadata:
# k-v形式,k和v都可以自定義
instance: c
test: a
version: v1
配置完成后重啟項(xiàng)目,可以看到配置文件中所配置的實(shí)例級(jí)別元數(shù)據(jù):
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。