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