原始碼地址:https://gitee.com/fighter3/eshop-project.git
持續更新中……
在上一節我們已經完成了Nacos Server的本地部署,這一節我們學習如何將Nacos作為註冊中心,管理微服務。
1、註冊中心簡介
1.1、什麼是註冊中心
在微服務的體系裡,註冊中心是最重要的元件之一,我們來簡單瞭解一下什麼是註冊中心。
註冊中心和DNS類似,大家想一想,我們平時訪問百度,是訪問 www.baidu.com ,還是直接訪問ip地址呢?
註冊中心就承擔了這樣一個“名單”的角色,它記錄了服務和服務地址的對映關係。在分散式架構中,服務會註冊到這裡,當服務需要呼叫其它服務時,就到這裡找到服務的地址,進行呼叫。
註冊中心的作用就是服務的註冊和服務的發現。
1.2、常見的註冊中心
- Netflix Eureka
- Alibaba Nacos
- HashiCorp Consul
- Apache ZooKeeper
- CoreOS Etcd
- CNCF CoreDNS
特性 | Eureka | Nacos | Consul | Zookeeper |
---|---|---|---|---|
CAP | AP | CP + AP | CP | CP |
健康檢查 | Client Beat | TCP/HTTP/MYSQL/Client Beat | TCP/HTTP/gRPC/Cmd | Keep Alive |
雪崩保護 | 有 | 有 | 無 | 無 |
自動登出例項 | 支援 | 支援 | 不支援 | 支援 |
訪問協議 | HTTP | HTTP/DNS | HTTP/DNS | TCP |
監聽支援 | 支援 | 支援 | 支援 | 支援 |
多資料中心 | 支援 | 支援 | 支援 | 不支援 |
跨註冊中心同步 | 不支援 | 支援 | 支援 | 不支援 |
SpringCloud整合 | 支援 | 支援 | 支援 | 支援 |
1.3、CAP原則與BASE理論
1.3.1、CAP原則
CAP 原則又稱 CAP 定理,指的是在一個分散式系統中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分割槽容錯性),三者不可得兼。
CAP 由 Eric Brewer 在 2000 年 PODC 會議上提出。該猜想在提出兩年後被證明成立,成為我們熟知的 CAP 定理。CAP 三者不可兼得。
特性 | 定理 |
---|---|
Consistency | 也叫做資料原子性,系統在執行某項操作後仍然處於一致的狀態。在分散式系統中,更新操作執行成功後所有的使用者都應該讀到最新的值,這樣的系統被認為是具有強一致性的。等同於所有節點訪問同一份最新的資料副本。 |
Availability | 每一個操作總是能夠在一定的時間內返回結果,這裡需要注意的是"一定時間內"和"返回結果"。一定時間內指的是,在可以容忍的範圍內返回結果,結果可以是成功或者是失敗。 |
Partition tolerance | 在網路分割槽的情況下,被分隔的節點仍能正常對外提供服務(分散式叢集,資料被分佈儲存在不同的伺服器上,無論什麼情況,伺服器都能正常被訪問)。 |
取捨原則
CAP 三個特性只能滿足其中兩個,那麼取捨的策略就共有三種:
- CA without P:如果不要求P(不允許分割槽),則C(強一致性)和A(可用性)是可以保證的。但放棄 P 的同時也就意味著放棄了系統的擴充套件性,也就是分散式節點受限,沒辦法部署子節點,這是違背分散式系統設計的初衷的。
- CP without A:如果不要求A(可用),相當於每個請求都需要在伺服器之間保持強一致,而P(分割槽)會導致同步時間無限延長(也就是等待資料同步完才能正常訪問服務),一旦發生網路故障或者訊息丟失等情況,就要犧牲使用者的體驗,等待所有資料全部一致了之後再讓使用者訪問系統。設計成 CP 的系統其實不少,最典型的就是分散式資料庫,如 Redis、HBase 等。對於這些分散式資料庫來說,資料的一致性是最基本的要求,因為如果連這個標準都達不到,那麼直接採用關係型資料庫就好,沒必要再浪費資源來部署分散式資料庫。
- AP without C:要高可用並允許分割槽,則需放棄一致性。一旦分割槽發生,節點之間可能會失去聯絡,為了高可用,每個節點只能用本地資料提供服務,而這樣會導致全域性資料的不一致性。典型的應用就如某米的搶購手機場景,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當你選擇完商品準備下單的時候,系統提示你下單失敗,商品已售完。這其實就是先在 A(可用性)方面保證系統可以正常的服務,然後在資料的一致性方面做了些犧牲,雖然多少會影響一些使用者體驗,但也不至於造成使用者購物流程的嚴重阻塞。
總結:
現如今,對於多數大型網際網路應用的場景,主機眾多、部署分散,而且現在的叢集規模越來越大,節點只會越來越多,所以節點故障、網路故障是常態,因此分割槽容錯性也就成為了一個分散式系統必然要面對的問題。那麼就只能在 C 和 A 之間進行取捨。但對於傳統的專案就可能有所不同,拿銀行的轉賬系統來說,涉及到金錢的對於資料一致性不能做出一絲的讓步,C 必須保證,出現網路故障的話,寧可停止服務,可以在 A 和 P 之間做取捨。
總而言之,沒有最好的策略,好的系統應該是根據業務場景來進行架構設計的,只有適合的才是最好的。
1.3.2、BASE理論
CAP 理論已經提出好多年了,難道真的沒有辦法解決這個問題嗎?也許可以做些改變。比如 C 不必使用那麼強的一致性,可以先將資料存起來,稍後再更新,實現所謂的 “最終一致性”。
這個思路又是一個龐大的問題,同時也引出了第二個理論 BASE 理論。
BASE:全稱 Basically Available(基本可用),Soft state(軟狀態),和 Eventually consistent(最終一致性)三個短語的縮寫,來自 ebay 的架構師提出。
BASE 理論是對 CAP 中一致性和可用性權衡的結果,其來源於對大型網際網路分散式實踐的總結,是基於 CAP 定理逐步演化而來的。其核心思想是:
既然無法做到強一致性(Strong consistency),但每個應用都可以根據自身的業務特點,採用適當的方式來使系統達到最終一致性(Eventual consistency)。
Basically Available(基本可用)
基本可用是指分散式系統在出現故障的時候,允許損失部分可用性(例如響應時間、功能上的可用性)。需要注意的是,基本可用絕不等價於系統不可用。
- 響應時間上的損失:正常情況下搜尋引擎需要在 0.5 秒之內返回給使用者相應的查詢結果,但由於出現故障(比如系統部分機房發生斷電或斷網故障),查詢結果的響應時間增加到了 1~2 秒。
- 功能上的損失:購物網站在購物高峰(如雙十一)時,為了保護系統的穩定性,部分消費者可能會被引導到一個降級頁面。
Soft state(軟狀態)
什麼是軟狀態呢?相對於原子性而言,要求多個節點的資料副本都是一致的,這是一種 “硬狀態”。
軟狀態是指允許系統存在中間狀態,而該中間狀態不會影響系統整體可用性。分散式儲存中一般一份資料會有多個副本,允許不同副本資料同步的延時就是軟狀態的體現。
Eventually consistent(最終一致性)
系統不可能一直是軟狀態,必須有個時間期限。在期限過後,應當保證所有副本保持資料一致性。從而達到資料的最終一致性。這個時間期限取決於網路延時,系統負載,資料複製方案設計等等因素。
實際上,不只是分散式系統使用最終一致性,關係型資料庫在某個功能上,也是使用最終一致性的,比如備份,資料庫的複製都是需要時間的,這個複製過程中,業務讀取到的值就是舊值。當然,最終還是達成了資料一致性。這也算是一個最終一致性的經典案例。
總結
總的來說,BASE 理論面向的是大型高可用可擴充套件的分散式系統,和傳統事務的 ACID 是相反的,它完全不同於 ACID 的強一致性模型,而是通過犧牲強一致性來獲得可用性,並允許資料在一段時間是不一致的。
2、引入Nacos作為註冊中心
啟動Nacos Server,我們發現服務列表裡空空如也,接下里我們會在專案裡整合Nacos Client,把我們前面開發的服務註冊到Nacos Server。
2.1、引入Nacos Client
Nacos與SpringCloud\Dubbo生態都能很好的融合,我們基於spring-cloud-alibaba引入nacos基礎jar。
首先將父專案引入spring-cloud\spring-cloud-alibaba依賴,首先看一下官方的版本說明:版本說明
SpringBoot我們引入的是2.2.2.RELEASE
版本,所以SpringCloud版本選擇Hoxton.RELEASE
,SpringCloud Alibaba版本選擇2.2.0.RELEASE
。
- 父專案管理依賴版本
在父專案pom.xml中新增:
<properties>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.version>
</properties>
<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>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 子專案引入Nacos
還是以user子模組為例,在user子模組的pom.xml中新增:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
這裡存在一個問題,spring-cloud-starter-alibaba-nacos-discovery需要指定版本,否則無法匯入,沒有查詢為什麼版本和SpringCloud Alibaba版本不一致。
2.2、服務註冊
- 在模組啟動類中新增註解
@EnableDiscoveryClient
開啟服務註冊發現功能
@SpringBootApplication
@MapperScan("cn.fighter3.mapper")
@EnableDiscoveryClient
public class EshopUserApplication {
public static void main(String[] args) {
SpringApplication.run(EshopUserApplication.class, args);
}
}
- 在配置檔案application.yml中新增服務名稱和Nacos Server地址
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
更多配置可以檢視:Nacos discovery
- 啟動專案,通過Nacos控制檯檢視,發現使用者服務已經註冊到了Nacos Server。
我們可以參考第五章,和上面的內容,完善其它幾個業務子模組,將其它幾個業務模組服務也註冊到Nacos註冊中心。這裡略去這一部分的內容,給大家看最後的效果:
好了,服務註冊已經完成,在下一章我們會接著學習服務如何遠端呼叫,請持續關注……
"簡單的事情重複做,重複的事情認真做,認真的事情有創造性地做!"——
我是三分惡,可以叫我老三/三分/三哥/三子,一個能文能武的全棧開發,我們們下期見!
參考:
【1】:小專欄《SpringCloudAlibaba微服務實戰 》
【3】:Spring Cloud 系列之 Alibaba Nacos 註冊中心(一)
【4】:Nacos discovery