服務(wù)發(fā)現(xiàn)如何做到持續(xù)維護(hù)服務(wù)地址在動(dòng)態(tài)運(yùn)維中的時(shí)效性?
遠(yuǎn)程服務(wù)的多樣性帶來(lái)了對(duì)“服務(wù)發(fā)現(xiàn)”概念的雙重理解。首先,我們有“百科全書(shū)式”的服務(wù)發(fā)現(xiàn),代表技術(shù)是UDDI。這種方法提供了從宏觀到微觀的信息層次,包括提供服務(wù)的企業(yè)背景(如企業(yè)實(shí)體、聯(lián)系方式、分類(lèi)目錄)到具體的服務(wù)程序接口細(xì)節(jié)(例如方法名稱、參數(shù)、返回值、技術(shù)規(guī)范)。它覆蓋了服務(wù)發(fā)現(xiàn)過(guò)程中的廣泛信息需求。
另一端,我們看到了類(lèi)似于DNS的“門(mén)牌號(hào)碼式”服務(wù)發(fā)現(xiàn)。這種方式專(zhuān)注于將服務(wù)提供者的全限定名轉(zhuǎn)換為實(shí)際的主機(jī)IP地址,其關(guān)注點(diǎn)更加狹窄。這種服務(wù)發(fā)現(xiàn)不深入到服務(wù)的具體提供商或其提供的方法細(xì)節(jié),而是假設(shè)服務(wù)消費(fèi)者已經(jīng)掌握這些信息。在這里,服務(wù)的定位信息被簡(jiǎn)化為“全限定名+端口號(hào)”的形式。
但隨著微服務(wù)的逐漸流行,服務(wù)的非正常宕機(jī)重啟和正常的上下線操作變得更加頻繁,僅靠著 DNS 服務(wù)器和負(fù)載均衡器等基礎(chǔ)設(shè)施,就顯得逐漸有些疲于應(yīng)對(duì),無(wú)法跟上服務(wù)變動(dòng)的步伐了。
隨著分布式系統(tǒng)的復(fù)雜性增加,服務(wù)發(fā)現(xiàn)成為了一個(gè)關(guān)鍵問(wèn)題,促使人們探索新的解決方案。ZooKeeper,一個(gè)分布式鍵值存儲(chǔ)框架,曾是解決服務(wù)注冊(cè)和發(fā)現(xiàn)問(wèn)題的熱門(mén)工具。它在微服務(wù)的早期階段,特別是在遠(yuǎn)程服務(wù)發(fā)現(xiàn)領(lǐng)域,占據(jù)了主導(dǎo)地位。然而,由于ZooKeeper是一個(gè)底層的分布式工具,它要求開(kāi)發(fā)者投入大量的工作來(lái)滿足服務(wù)發(fā)現(xiàn)的具體需求。
2014年,經(jīng)過(guò)Netflix內(nèi)部長(zhǎng)時(shí)間的實(shí)踐考驗(yàn),Eureka這一專(zhuān)為服務(wù)發(fā)現(xiàn)設(shè)計(jì)的工具宣布開(kāi)源。Eureka的開(kāi)源不僅標(biāo)志著其成熟和可靠,而且由于其后被Spring Cloud納入,成為了Java開(kāi)發(fā)者在遠(yuǎn)程服務(wù)發(fā)現(xiàn)方面的首選解決方案,大大減少了服務(wù)注冊(cè)的工作量。
到了2018年,隨著Spring Cloud Eureka進(jìn)入維護(hù)模式,Consul和Nacos這兩個(gè)新興的服務(wù)發(fā)現(xiàn)框架迅速崛起,接過(guò)了Eureka的接力棒。這些現(xiàn)代服務(wù)發(fā)現(xiàn)框架的發(fā)展已經(jīng)非常成熟,它們不僅支持通過(guò)DNS或HTTP進(jìn)行地址轉(zhuǎn)換,還提供了包括服務(wù)健康檢查、集中配置管理、鍵值存儲(chǔ)、跨數(shù)據(jù)中心數(shù)據(jù)同步等多種高級(jí)功能,標(biāo)志著應(yīng)用級(jí)服務(wù)發(fā)現(xiàn)的一個(gè)高峰。
進(jìn)入云原生時(shí)代,基礎(chǔ)設(shè)施的靈活性被極大增強(qiáng),人們開(kāi)始重新關(guān)注使用基礎(chǔ)設(shè)施本身來(lái)實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)的透明化方式。目前,探索在基礎(chǔ)設(shè)施和網(wǎng)絡(luò)協(xié)議層面,如何實(shí)現(xiàn)對(duì)應(yīng)用幾乎無(wú)感知且便捷的服務(wù)發(fā)現(xiàn),成為了研究的主要方向。
服務(wù)發(fā)現(xiàn)要解決注冊(cè)、維護(hù)和發(fā)現(xiàn)三大功能問(wèn)題
服務(wù)發(fā)現(xiàn)流程中包含三個(gè)關(guān)鍵環(huán)節(jié):服務(wù)注冊(cè)、服務(wù)維護(hù)、和服務(wù)發(fā)現(xiàn),每個(gè)環(huán)節(jié)對(duì)于維護(hù)系統(tǒng)的高效運(yùn)轉(zhuǎn)都至關(guān)重要。
服務(wù)注冊(cè)
服務(wù)注冊(cè)是服務(wù)發(fā)現(xiàn)機(jī)制的第一步。當(dāng)服務(wù)啟動(dòng)時(shí),它需要以某種方式(例如,通過(guò)API調(diào)用、事件消息發(fā)布、在ZooKeeper或Etcd中記錄位置、或?qū)⑿畔⒋嫒霐?shù)據(jù)庫(kù)等)將其坐標(biāo)信息注冊(cè)到服務(wù)注冊(cè)中心。這一過(guò)程既可以由應(yīng)用程序自身通過(guò)特定的注解或配置完成(如Spring Cloud的@EnableDiscoveryClient注解),也可以由容器管理框架(例如Kubernetes)自動(dòng)處理。
服務(wù)維護(hù)
服務(wù)維護(hù)確保服務(wù)列表的準(zhǔn)確性和更新性。盡管許多服務(wù)發(fā)現(xiàn)框架提供了服務(wù)下線的機(jī)制,但并非所有服務(wù)都能保證優(yōu)雅地下線,可能因?yàn)楣收匣蚓W(wǎng)絡(luò)問(wèn)題突然中斷。因此,服務(wù)發(fā)現(xiàn)框架需要通過(guò)各種手段(如HTTP、TCP協(xié)議、長(zhǎng)連接、心跳檢測(cè)、探針或進(jìn)程狀態(tài)監(jiān)測(cè)等)自動(dòng)監(jiān)控服務(wù)的健康狀況,并將不健康的服務(wù)自動(dòng)下線,以避免向消費(fèi)者提供無(wú)法訪問(wèn)的服務(wù)地址。
服務(wù)發(fā)現(xiàn)
服務(wù)發(fā)現(xiàn)是指消費(fèi)者查詢并獲得服務(wù)實(shí)際坐標(biāo)信息的過(guò)程。這通常通過(guò)HTTP API請(qǐng)求或DNS查找操作完成,允許消費(fèi)者通過(guò)服務(wù)標(biāo)識(shí)(如Eureka的ServiceID、Nacos的服務(wù)名或通用的FQDN)找到服務(wù)的具體地址。盡管這里著重討論的是核心功能,許多服務(wù)發(fā)現(xiàn)框架還提供了一系列附加功能,如負(fù)載均衡、流量管理、鍵值存儲(chǔ)、元數(shù)據(jù)管理和業(yè)務(wù)分組等,進(jìn)一步增強(qiáng)了服務(wù)發(fā)現(xiàn)的能力和靈活性。
為什么服務(wù)發(fā)現(xiàn)對(duì) CAP 如此關(guān)注、如此敏感呢?
在概念模型中,服務(wù)中心所處的地位是這樣的:提供者在服務(wù)發(fā)現(xiàn)中注冊(cè)、續(xù)約和下線自己的真實(shí)坐標(biāo),消費(fèi)者根據(jù)某種符號(hào)從服務(wù)發(fā)現(xiàn)中獲取到真實(shí)坐標(biāo),它們都可以看作是系統(tǒng)中平等的微服務(wù)。我們來(lái)看看這個(gè)概念模型示意圖:
服務(wù)發(fā)現(xiàn)在系統(tǒng)中的作用不同于其他服務(wù),因?yàn)樗撬蟹?wù)相互通信的基礎(chǔ)。就像配置中心一樣,服務(wù)發(fā)現(xiàn)也變得非常關(guān)鍵,因?yàn)閹缀跛蟹?wù)都依賴它。如果服務(wù)發(fā)現(xiàn)出問(wèn)題,整個(gè)系統(tǒng)都會(huì)受影響。因此,確保服務(wù)發(fā)現(xiàn)的穩(wěn)定和可靠是非常重要的,需要在技術(shù)上做好準(zhǔn)備,以防任何可能的問(wèn)題。
所以,在分布式系統(tǒng)中,服務(wù)注冊(cè)中心一般會(huì)以內(nèi)部小集群的方式進(jìn)行部署,提供三個(gè)或者五個(gè)節(jié)點(diǎn)(通常最多七個(gè),一般也不會(huì)更多了,否則日志復(fù)制的開(kāi)銷(xiāo)太高)來(lái)保證高可用性。你可以看看下面給出的這個(gè)例子:
我拿前面提到的最有代表性的 Eureka 和 Consul 來(lái)舉個(gè)例子。
在分布式系統(tǒng)設(shè)計(jì)中,對(duì)于數(shù)據(jù)一致性和系統(tǒng)可用性的取舍常常是一個(gè)核心討論點(diǎn),歸結(jié)為CAP理論中的兩種選擇:一致性(Consistency)與可用性(Availability),同時(shí)還要考慮分區(qū)容錯(cuò)性(Partition tolerance)。Consul和Eureka這兩個(gè)服務(wù)發(fā)現(xiàn)工具就很好地體現(xiàn)了不同的設(shè)計(jì)選擇。
Consul的CP取向
Consul采用Raft協(xié)議,這是一個(gè)強(qiáng)調(diào)一致性的協(xié)議。在Consul的設(shè)計(jì)中,只有當(dāng)多數(shù)節(jié)點(diǎn)確認(rèn)寫(xiě)入操作后,服務(wù)的注冊(cè)或變更才會(huì)被確認(rèn)。這種方式確保了任何時(shí)候從集群外部讀取的服務(wù)發(fā)現(xiàn)信息都是一致的,即便這可能會(huì)犧牲一些可用性——在極端情況下,如果達(dá)不到多數(shù)節(jié)點(diǎn)的確認(rèn),服務(wù)更新操作可能會(huì)被阻塞。Consul通過(guò)這種設(shè)計(jì),優(yōu)先保證了系統(tǒng)的一致性(Consistency)和分區(qū)容錯(cuò)性(Partition tolerance),屬于CAP理論中的CP模型。
Eureka的AP取向
與Consul不同,Eureka的設(shè)計(jì)更傾向于保證系統(tǒng)的可用性(Availability)。它的節(jié)點(diǎn)間通過(guò)異步復(fù)制來(lái)交換服務(wù)注冊(cè)信息,這意味著服務(wù)注冊(cè)或變動(dòng)可以立即在當(dāng)前節(jié)點(diǎn)上反映出來(lái),而不需要等待這些信息被復(fù)制到其他節(jié)點(diǎn)。這種設(shè)計(jì)雖然提高了系統(tǒng)的響應(yīng)速度和可用性,使得即使在部分節(jié)點(diǎn)不可用的情況下,服務(wù)注冊(cè)和發(fā)現(xiàn)仍然可以繼續(xù)工作,但它犧牲了一致性——不同節(jié)點(diǎn)間的信息可能會(huì)出現(xiàn)暫時(shí)的不一致。Eureka通過(guò)這種方式,優(yōu)先保證了系統(tǒng)的可用性(Availability)和分區(qū)容錯(cuò)性(Partition tolerance),符合CAP理論中的AP模型。
微服務(wù)架構(gòu)中的一個(gè)重要設(shè)計(jì)原則是“通過(guò)服務(wù)來(lái)實(shí)現(xiàn)獨(dú)立自治的組件”(Componentization via Services),微服務(wù)強(qiáng)調(diào)通過(guò)“服務(wù)”(Service)而不是“類(lèi)庫(kù)”(Library)來(lái)構(gòu)建組件,這是因?yàn)閮烧呔哂泻艽蟮牟顒e:類(lèi)庫(kù)是在編譯期靜態(tài)鏈接到程序中的,通過(guò)本地調(diào)用來(lái)提供功能;而服務(wù)是進(jìn)程外組件,通過(guò)遠(yuǎn)程調(diào)用來(lái)提供功能。