谈服务发现的背景、架构以及落地方案
http://www.infoq.com/cn/articles/background-architecture-and-solutions-of-service-discovery
在開始之前,我們先來回顧下業(yè)內(nèi)對于微服務(wù)架構(gòu)的定義。簡單來說,微服務(wù)就是用一組小服務(wù)的方式來構(gòu)建一個應(yīng)用,服務(wù)獨立運行在不同的進程中,服務(wù)之間通過輕量的通訊機制(如RESTful接口)來交互,并且服務(wù)可以通過自動化部署方式獨立部署。
從定義中不難理解,微服務(wù)架構(gòu)其實也就意味著更多的獨立服務(wù),并且這些服務(wù)之間需要頻繁交互和通信。通訊可以使用RESTful的方式,但通訊之前服務(wù)和服務(wù)之間是如何知道彼此的地址的(類比打電話)?這個時候就需要引入服務(wù)發(fā)現(xiàn)的概念。簡單來說,服務(wù)發(fā)現(xiàn)就是服務(wù)或者應(yīng)用之間互相定位的過程,它也并不是什么新鮮的概念。那在微服務(wù)的架構(gòu)體系中,我們應(yīng)該如何落地服務(wù)發(fā)現(xiàn)?又有哪些可用的開源方案?帶著這些問題,InfoQ記者采訪了微服務(wù)專家宋瀟男。
InfoQ:談?wù)勈裁词欠?wù)發(fā)現(xiàn)?你是如何理解服務(wù)發(fā)現(xiàn)的?在整個微服務(wù)架構(gòu)中,服務(wù)發(fā)現(xiàn)起到什么作用?
宋瀟男:服務(wù)發(fā)現(xiàn)這個事情可以說是自古有之,當我們使用網(wǎng)絡(luò)打印機的時候,首先要通過WS-Discovery或者Bonjour協(xié)議發(fā)現(xiàn)并連接網(wǎng)絡(luò)中存在的打印服務(wù)。當我們使用藍牙耳機或者音箱的時候,首先要通過SDP協(xié)議發(fā)現(xiàn)并連接附近的藍牙音頻服務(wù),這些服務(wù)發(fā)現(xiàn)方式可以讓用戶不必關(guān)心服務(wù)提供者的具體網(wǎng)絡(luò)位置(IP地址、端口等)和配置方步驟,只需選擇和連接即可使用這些服務(wù)。
之前做單體式應(yīng)用開發(fā)時很少提及服務(wù)發(fā)現(xiàn),因為傳統(tǒng)單體應(yīng)用動態(tài)性不強,不會頻繁的更新和重新發(fā)布,也較少進行自動伸縮。傳統(tǒng)單體應(yīng)用的網(wǎng)絡(luò)位置很少發(fā)生變化,在發(fā)生變化時,由運維人員手工更新一下它們的配置文件,也不是什么太大的問題。
而微服務(wù)架構(gòu)則完全不同,微服務(wù)會被頻繁的更新和重新發(fā)布,頻繁的根據(jù)負載情況進行動態(tài)伸縮,微服務(wù)實例還可能受資源調(diào)度影響而從一臺服務(wù)器遷移到另一臺服務(wù)器。
總而言之,在微服務(wù)架構(gòu)中,微服務(wù)實例的網(wǎng)絡(luò)位置發(fā)生變化是一種常態(tài),所以必須提供一種機制,使得服務(wù)消費者在服務(wù)提供者的網(wǎng)絡(luò)位置發(fā)生變化時,能夠及時獲得最新的位置信息,一般是提供一個網(wǎng)絡(luò)位置穩(wěn)定的服務(wù)注冊中心,服務(wù)提供者的網(wǎng)絡(luò)位置被注冊到注冊中心,并在網(wǎng)絡(luò)位置發(fā)生變化的時候及時更新,而服務(wù)消費者定期向注冊中心獲取服務(wù)提供者的最新位置信息,這就是最基本的服務(wù)發(fā)現(xiàn)機制。較為復(fù)雜的服務(wù)發(fā)現(xiàn)實現(xiàn)除了服務(wù)提供者的位置信息外,還可以向服務(wù)消費者提供服務(wù)提供者的描述信息、狀態(tài)信息和資源使用信息,以供服務(wù)消費者實現(xiàn)更為復(fù)雜的服務(wù)選擇邏輯。
之前做單體式應(yīng)用的時候,有個和服務(wù)發(fā)現(xiàn)類似的概念叫服務(wù)目錄,其實這兩個概念并不沖突,也不存在明顯的替代關(guān)系。服務(wù)目錄更像是一個市場,是一個把服務(wù)當作產(chǎn)品上架展示,供用戶了解和購買的渠道,使用者是人;而服務(wù)發(fā)現(xiàn)是供服務(wù)注冊自身和查詢其他服務(wù)相關(guān)信息的一種機制,使用者是程序。在微服務(wù)架構(gòu)中,服務(wù)發(fā)現(xiàn)作為一種基本機制,必須得到實現(xiàn),而服務(wù)目錄則是一個可選項,如果有的話,用戶體驗會更好一些。
InfoQ:能否以一個請求為例,介紹下服務(wù)發(fā)現(xiàn)的流程?
宋瀟男:服務(wù)發(fā)現(xiàn)的流程比較簡單,去年我翻譯了Chris Richardson的一些微服務(wù)文章,對服務(wù)發(fā)現(xiàn)的流程做了些基本的描述,比較完備的說,服務(wù)發(fā)現(xiàn)流程應(yīng)該分為兩種模式:
客戶端發(fā)現(xiàn):
服務(wù)提供者的實例在啟動時或者位置信息發(fā)生變化時會向服務(wù)注冊表注冊自身,在停止時會向服務(wù)注冊表注銷自身,如果服務(wù)提供者的實例發(fā)生故障,在一段時間內(nèi)不發(fā)送心跳之后,也會被服務(wù)注冊表注銷。
服務(wù)消費者的實例會向服務(wù)注冊表查詢服務(wù)提供者的位置信息,然后通過這些位置信息直接向服務(wù)提供者發(fā)起請求。
服務(wù)端發(fā)現(xiàn):
第一步與客戶端發(fā)現(xiàn)相同。
服務(wù)消費者不直接向服務(wù)注冊表查詢,也不直接向服務(wù)提供者發(fā)起請求,而是將對服務(wù)提供者的請求發(fā)往一個中央路由器或者負載均衡器,中央路由器或者負載均衡器查詢服務(wù)注冊表獲取服務(wù)提供者的位置信息,并將請求轉(zhuǎn)發(fā)給服務(wù)提供者。
這兩種模式各有利弊,客戶端發(fā)現(xiàn)模式的優(yōu)勢是,服務(wù)消費者向服務(wù)提供者發(fā)起請求時比服務(wù)端發(fā)現(xiàn)模式少了一次網(wǎng)絡(luò)跳轉(zhuǎn),劣勢是服務(wù)消費者需要內(nèi)置特定的服務(wù)發(fā)現(xiàn)客戶端和服務(wù)發(fā)現(xiàn)邏輯;服務(wù)端發(fā)現(xiàn)模式的優(yōu)勢是服務(wù)消費者無需內(nèi)置特定的服務(wù)發(fā)現(xiàn)客戶端和服務(wù)發(fā)現(xiàn)邏輯,劣勢是多了一次網(wǎng)絡(luò)跳轉(zhuǎn),并且需要基礎(chǔ)設(shè)施環(huán)境提供中央路由機制或者負載均衡機制。目前客戶端發(fā)現(xiàn)模式應(yīng)用的多一些,因為這種模式的對基礎(chǔ)設(shè)施環(huán)境沒有特殊的要求,和基礎(chǔ)設(shè)施環(huán)境也沒有過多的耦合性。
InfoQ:目前都有哪些服務(wù)發(fā)現(xiàn)的解決方案?能否詳細介紹下各個解決方案的優(yōu)缺點?
宋瀟男:其實可選方案并不多,所以選擇起來也并不糾結(jié)。DNS可以算是最為原始的服務(wù)發(fā)現(xiàn)系統(tǒng),但是在服務(wù)變更較為頻繁,即服務(wù)的動態(tài)性很強的時候,DNS記錄的傳播速度可能會跟不上服務(wù)的變更速度,這將導致在一定的時間窗口內(nèi)無法提供正確的服務(wù)位置信息,所以這種方案只適合在比較靜態(tài)的環(huán)境中使用,不適用于微服務(wù)。
基于ZooKeeper、Etcd等分布式鍵值對存儲服務(wù)來建立服務(wù)發(fā)現(xiàn)系統(tǒng)在現(xiàn)在看起來也不是一種很好的方案,一方面是因為它們只能提供基本的數(shù)據(jù)存儲功能,還需要在外圍做大量的開發(fā)才能形成完整的服務(wù)發(fā)現(xiàn)方案。另一方面是因為它們都是強一致性系統(tǒng),在集群發(fā)生分區(qū)時會優(yōu)先保證一致性、放棄可用性,而服務(wù)發(fā)現(xiàn)方案更注重可用性,為了保證可用性可以選擇最終一致性,這兩方面原因共同導致了ZooKeeper、Etcd這類系統(tǒng)越來越遠離服務(wù)發(fā)現(xiàn)方案的備選清單,像SmartStack這種依賴ZooKeeper的服務(wù)發(fā)現(xiàn)方案也逐漸發(fā)覺ZooKeeper成了它的薄弱環(huán)節(jié)。
Netflix的Eureka是現(xiàn)在最流行的服務(wù)發(fā)現(xiàn)方案,服務(wù)端和客戶端都是Java編寫的,針對微服務(wù)場景,并且和Netflix的其他開源項目以及Spring Cloud都有著非常好的整合,具備良好的生態(tài),如果你使用Java語言開發(fā),Eureka幾乎是你的最佳選擇。與ZooKeeper、Etcd或者依賴它們的方案不同,Eureka是個專門為服務(wù)發(fā)現(xiàn)從零開始開發(fā)的項目,Eureka以可用性為先,可以在多種故障期間保持服務(wù)發(fā)現(xiàn)和服務(wù)注冊功能可用,雖然此時會存在一些數(shù)據(jù)錯誤,但是Eureka的設(shè)計原則是“存在少量的錯誤數(shù)據(jù),總比完全不可用要好”,并且可以在故障恢復(fù)之后按最終一致性進行狀態(tài)合并,清理掉錯誤數(shù)據(jù)。
前面為什么說Eureka“幾乎是”最佳選擇,因為它還有個強大的對手Consul。Consul是HashiCorp公司的商業(yè)產(chǎn)品,它有一個開源的基礎(chǔ)版本,這個版本在基本的服務(wù)發(fā)現(xiàn)功能之外,還提供了多數(shù)據(jù)中心部署能力,包括內(nèi)存、存儲使用情況在內(nèi)的細粒度服務(wù)狀態(tài)檢測能力,和用于服務(wù)配置的鍵值對存儲能力(這是一把雙刃劍,使用它可以帶來便捷,但是也意味著和Consul的較強耦合性),這幾個能力Eureka目前都沒有。而Consul的商業(yè)版本功能更為強大,如果你不介意依賴單一公司提供的商業(yè)產(chǎn)品,也可以從Consul的開源版本開始用起。
最后還有一個比較有趣的方案是SkyDNS,這是一個結(jié)合古老的DNS技術(shù)和時髦的Go語言、Raft算法的有趣項目,主要在Kubernetes里使用,因為Kubernetes有一層較為穩(wěn)定的Service抽象,有點類似于問題2里描述的服務(wù)端服務(wù)發(fā)現(xiàn)方式,所以不存在DNS時間窗口的問題。
這里我就不對上述的各個方案做具體功能特性上的對比了,我在做方案選型時不太喜歡做這種微觀對比,因為具體的功能特性是易變的,今天Consul出一個新功能,明天Eureka出一個新特性,如果依賴這個做選擇,會搖擺不定,我更注重這些方案背后的一些根深蒂固的必然性,比如ZooKeeper永遠都不會為了服務(wù)發(fā)現(xiàn)放棄它的強一致性,所以即使它有再多適合服務(wù)發(fā)現(xiàn)的功能特性,它也不會成為服務(wù)發(fā)現(xiàn)的優(yōu)選方案,再比如Consul由一家商業(yè)軟件公司提供,那么必然或多或少的存在商業(yè)軟件的某些弊端,如果你非常在意這些弊端,Consul再強大,你也不會選擇它。
InfoQ:你推薦使用哪種解決方案?它如何與整個的服務(wù)架構(gòu)結(jié)合?
宋瀟男:其實在上一個問題的回答中,我的傾向性已經(jīng)非常明顯了,我推薦Eureka,如果你想使用商業(yè)產(chǎn)品,我也不會推薦Consul,所以商業(yè)產(chǎn)品我當然會推薦普元的(笑)。當然,普元并不提供單獨的服務(wù)注冊產(chǎn)品,普元在微服務(wù)開發(fā)和運行平臺中基于Eureka提供服務(wù)發(fā)現(xiàn)能力。
至于第二個問題,因為Eureka和Spring Boot、Spring Cloud都整合的非常好,所以使用起來非常簡單,只需在pom中加入對Spring Cloud Eureka Server的依賴并在代碼中加入@EnableEurekaServer,即可創(chuàng)建一個Eureka Server,在服務(wù)提供者和消費者這邊,只需在pom中加入對Spring Cloud Eureka的依賴并在代碼中加入@EnableDiscoveryClient,代碼運行時即可自動將自身注冊到Eureka Server中,然后使用getInstances方法即可查詢服務(wù)實例的位置信息,這個時候還可以使用客戶端負載均衡方案Netflix Ribbon對這些實例做負載均衡。如果你在服務(wù)架構(gòu)的其他部分也使用Netflix和Spring Cloud提供的模塊,那么集成起來也非常容易。
InfoQ:落地服務(wù)發(fā)現(xiàn)的難點是什么?
宋瀟男:落地服務(wù)發(fā)現(xiàn)的難點主要來自于分布式系統(tǒng)本身的復(fù)雜性和對業(yè)務(wù)系統(tǒng)的侵入性。因為幾乎所有服務(wù)提供者和服務(wù)消費者都對服務(wù)發(fā)現(xiàn)服務(wù)存在依賴,如果服務(wù)發(fā)現(xiàn)服務(wù)出現(xiàn)問題,將會造成大范圍的影響,所以服務(wù)發(fā)現(xiàn)服務(wù)自身的可用性至關(guān)重要。
為了保證服務(wù)發(fā)現(xiàn)服務(wù)本身的可用性,除了對服務(wù)發(fā)現(xiàn)服務(wù)進行本地的多節(jié)點部署之外,往往還需要跨越多個可用區(qū)甚至多個數(shù)據(jù)中心部署,以確保服務(wù)發(fā)現(xiàn)服務(wù)可以在多個層次的軟硬件故障中存活。在服務(wù)提供者和服務(wù)消費者數(shù)量眾多時,服務(wù)發(fā)現(xiàn)服務(wù)的性能也可能會成為問題。上述這些問題和分布式系統(tǒng)普遍存在的問題一致,只要在技術(shù)上做出充分準備,都是可以解決的,在此不做贅述。
更大的難點在某種程度上是非技術(shù)問題,現(xiàn)有的服務(wù)發(fā)現(xiàn)方案都或多或少的對業(yè)務(wù)系統(tǒng)存在侵入性,會改變業(yè)務(wù)系統(tǒng)的開發(fā)模式,例如在開發(fā)階段需要引入特殊的客戶端和服務(wù)的注冊、查詢過程。給開發(fā)帶來新的復(fù)雜度倒不是什么特別大的問題,因為這些復(fù)雜度可以通過技術(shù)工具降低,比如普元現(xiàn)在在做的微服務(wù)開發(fā)平臺就可以使這些開發(fā)過程中的額外工作自動化,更重要的是服務(wù)發(fā)現(xiàn)方案一旦確定,之后再做更換的成本會非常高,在對方案進行推廣的時候,很可能會引起業(yè)務(wù)部門的擔憂,并因此遇到阻力。
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/9250959.html
總結(jié)
以上是生活随笔為你收集整理的谈服务发现的背景、架构以及落地方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微服务实践分享(3)服务发现
- 下一篇: 美团点评业务之技术解密,日均请求数十亿次