10 張圖搞懂服務註冊發現機制
在微服務架構或分散式環境下,服務註冊與發現技術不可或缺,這也是程式設計師進階之路必須要掌握的核心技術之一,本文透過圖解的方式帶領大家輕輕鬆鬆掌握。
引入服務註冊與發現元件的原因
先來看一個問題,假如現在我們要做一個商城專案,作為架構師的你應該怎樣設計系統的架構?你心裡肯定在想:這還不容易直接照搬淘寶的架構不就行了。但在現實的創業環境中一個專案可能是九死一生,如果一開始投入巨大的人力和財力,一旦專案失敗損失就很大。
作為一位有經驗的架構師需要結合公司財力、人力投入預算等現狀選擇最適合眼下的架構才是王道。大型網站都是從小型網站發展而來,架構也是一樣。
任何一個大型網站的架構都不是從一開始就一層不變的,而是隨著使用者量和資料量的不斷增加不斷迭代演進的結果。
在架構不斷迭代演進的過程中我們會遇到很多問題,技術發展的本質就是不斷發現問題再解決問題,解決問題又發現問題。
單體架構
在系統建立之初可能不會有特別多的使用者,將所有的業務打成一個應用包放在tomcat容器中執行,與資料庫共用一臺伺服器,這種架構一般稱之為單體架構。
在初期這種架構的效率非常高,根據使用者的反饋可以快速迭代上線。但是隨著使用者量增加,一臺服務的記憶體和CPU吃緊,很容易造成瓶頸,新的問題來了怎麼解決呢?
應用與資料分離
隨著使用者請求量增加,一臺伺服器的記憶體和CPU持續飆升,使用者請求響應時間變慢。這時候可以考慮將應用與資料庫拆開,各自使用一臺伺服器,你看問題又解決了吧。
突然有一天掃地阿姨不小心碰了電線,其中一臺伺服器掉電了,使用者所有的請求都報錯,隨之而來的是一系列投訴電話。
叢集部署
單例項很容易造成單點問題,比如遇到伺服器故障或者服務能力瓶頸,那怎麼辦?聰明的你肯定想到了,用叢集呀。
叢集部署是指將應用部署在多個伺服器或者虛機上,使用者透過服務均衡隨機訪問其中的一個例項,從而使多個例項的流量均衡,如果一個例項出現故障可以將其下線,其他例項不受影響仍然可以對外提供服務。
隨著使用者數量快速增加,老闆決定增加投入擴大團隊規模。開發團隊壯大後效率並沒有得到顯著的提高,以前小團隊可以一週迭代上線一次,現在至少需要兩到三週時間。
業務邏輯越來越複雜,程式碼間耦合很嚴重,修改一行程式碼可能引入幾個線上問題。架構師意識到需要進行架構重構。
微服務架構
當單體架構演進到一定階段後開發測試的複雜性都會成本增加,團隊規模的擴大也會使得各自工作耦合性更嚴重,牽一髮而動全身就是這種場景。
單體架構遇到瓶頸了,微服務架構就橫空出世了。微服務就是將之前的單體服務按照業務維度進行拆分,拆分粒度可大可小,拆分時機可以分節奏進行。最佳實踐是先將一些獨立的功能從單體中剝離出來抽成一個或多個微服務,這樣可以保障業務的連續性和穩定性。
如上圖將一個商用應用拆分為六個獨立微服務。六個微服務可以使用Docker容器化進行多例項部署。
架構演化到這裡遇到了一個難題,如果要查詢使用者所有的訂單,使用者服務可能會依賴訂單服務,使用者服務如何與訂單服務互動呢?訂單服務有多個例項該訪問哪一個?
通常有幾種解決辦法:
(1)服務地址硬編碼
服務的地址寫死在資料庫或者配置檔案,透過訪問DNS域名進行定址路由。
服務B的地址硬編碼在資料庫或者配置檔案中,服務A首先需要拿到服務B的地址,然後透過DNS伺服器解析獲取其中一例項的真實地址,最後可以向服務B發起請求。
如果遇到大促活動需要對服務例項擴容,大促完需要對服務例項進行下線,運維人員要做大量的手工操作,非常容易誤操作。
(2)服務動態註冊與發現
服務地址硬編碼還有一個非常致命的問題,如果一臺例項掛了,運維人員可能不能及時感知到,導致一部分使用者的請求會異常。
引入服務註冊與發現元件可以很好解決上面遇到的問題,避免過多的人工操作。
架構演進總結
在單體架構中一個應用程式就是一個服務包,包內的模組透過函式方法相互呼叫,模型足夠簡單,根本沒有服務註冊和發現一說。
在微服務架構中會將一個應用程式拆分為多個微服務,微服務會部署在不同的伺服器、不同的容器、甚至多資料中心,微服務間要相互呼叫,服務註冊和發現成為了一個不可或缺的元件。
服務註冊與發現基本原理
服務註冊與發現是分為註冊和發現兩個關鍵的步驟。
服務註冊:服務程式在註冊中心註冊自己的後設資料資訊。通常包括主機和埠號,有時還有身份驗證資訊,協議,版本號,以及執行環境的資訊。
服務發現:客戶端服務程式向註冊中心發起查詢,來獲取服務的資訊。服務發現的一個重要作用就是提供給客戶端一個可用的服務列表。
服務註冊
服務註冊有兩種形式:客戶端註冊和代理註冊。
客戶端註冊
客戶端註冊是服務自己要負責註冊與登出的工作。當服務啟動後註冊執行緒向註冊中心註冊,當服務下線時登出自己。
這種方式的缺點是註冊登出邏輯與服務的業務邏輯耦合在一起,如果服務使用不同語言開發,那需要適配多套服務註冊邏輯。代理註冊
代理註冊由一個單獨的代理服務負責註冊與登出。當服務提供者啟動後以某種方式通知代理服務,然後代理服務負責向註冊中心發起註冊工作。
這種方式的缺點是多引用了一個代理服務,並且代理服務要保持高可用狀態。
服務發現
服務發現也分為客戶端發現和代理發現。
客戶端發現
客戶端發現是指客戶端負責向註冊中心查詢可用服務地址,獲取到所有的可用例項地址列表後客戶端根據負載均衡演算法選擇一個例項發起請求呼叫。
這種方式非常直接,客戶端可以控制負載均衡演算法。但是缺點也很明顯,獲取例項地址、負載均衡等邏輯與服務的業務邏輯耦合在一起,如果服務發現或者負載平衡有變化,那麼所有的服務都要修改重新上線。
代理發現
代理發現是指新增一個路由服務負責服務發現獲取可用的例項列表,服務消費者如果需要呼叫服務A的一個例項可以直接將請求發往路由服務,路由服務根據配置好的負載均衡演算法從可用的例項列表中選擇一個例項將請求轉發過去即可,如果發現例項不可用,路由服務還可以自行重試,服務消費者完全不用感知。
心跳機制
如果服務有多個例項,其中一個例項出現當機,註冊中心是可以實時感知到,並且將該例項資訊從列表中移出,也稱為摘機。
如何實現摘機?業界比較常用的方式是透過心跳檢測的方式實現,心跳檢測有主動和被動兩種方式。
被動檢測是指服務主動向註冊中心傳送心跳訊息,時間間隔可自定義,比如配置5秒傳送一次,註冊中心如果在三個週期內比如說15秒內沒有收到例項的心跳訊息,就會將該例項從列表中移除。
上圖中服務A的例項2已經當機不能主動給註冊中心傳送心跳訊息,15秒之後註冊就會將例項2移除掉。
主動檢測是註冊中心主動發起,每隔幾秒中會給所有列表中的服務例項傳送心跳檢測訊息,如果多個週期內未傳送成功或未收到回覆就會主動移除該例項。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2926779/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一文搞懂服務註冊發現的原理與實現
- Zookeeper實現服務註冊/發現
- Nacos服務註冊與發現
- NodeJs服務註冊與服務發現實現NodeJS
- 微服務4:服務註冊與發現微服務
- 【微服務之Eureka服務註冊發現】微服務
- go微服務系列(二) - 服務註冊/服務發現Go微服務
- Eureka實現服務註冊與發現
- apisix~整合服務發現註冊中心API
- Nacos服務註冊與發現原理
- 聊聊微服務的服務註冊與發現!微服務
- 【SpringCloud】(二):服務發現和服務註冊SpringGCCloud
- 微服務之服務註冊和服務發現篇微服務
- 實現etcd服務註冊與發現
- 三. SpringCloud服務註冊與發現SpringGCCloud
- Nacos 服務註冊與發現原理分析
- springcloud之服務註冊與發現SpringGCCloud
- Nacos服務註冊與發現的原理
- 小白入門微服務(4) – 服務註冊與服務發現微服務
- 小白入門微服務(4) - 服務註冊與服務發現微服務
- consul服務註冊與服務發現的巨坑
- go-kit微服務:服務註冊與發現Go微服務
- 微服務SpringCloud之服務註冊與發現微服務SpringGCCloud
- Dubbo+Nacos實現服務註冊和發現
- 用 etcd 實現服務註冊和發現
- 服務註冊與發現的原理和實現
- netty叢集(一)-服務註冊發現Netty
- SpringColud Eureka的服務註冊與發現SpringGC
- 服務註冊與發現【Eureka】- Eureka簡介
- SpringCloud(3)---Eureka服務註冊與發現SpringGCCloud
- 分散式(一) 搞定服務註冊與發現分散式
- SpringCloud服務的註冊與發現(Eureka)SpringGCCloud
- Getway實現nacos註冊及服務轉發
- 04-Consul服務註冊與發現
- 微服務Consul系列之服務註冊與發現微服務
- Choerodon 的微服務之路(三):服務註冊與發現微服務
- 微服務5:服務註冊與發現(實踐篇)微服務
- Spring Cloud Eureka 實現服務註冊與發現SpringCloud