摘要:本文講了關于服務發現的很多干貨內容,核心內容為服務發現組件的選擇、網關的介紹、 客戶端側如何發給已發現的服務,
本文分享自華為云社區《分布式場景下,如何對外提供易變的服務,打造可靠的注冊中心?》,作者:breakDawn,
隨著云原生的概念越來越火,服務的架構應該如何發展和演進,成為很多程式員關心的話題,大名鼎鼎的《深入理解java虛擬機》一書作者于21年推出了新作《鳳凰架構》,從這本書中可以看到當前時下很多最新的技識訓者理念,
本博文將沉淀發布這本書的學習筆記和思考, 如果希望了解更加詳細的內容,歡迎購買該書繼續詳細學習,
從類別庫到服務
1 服務發現
1.1 服務發現的意義
以前是DNS以及DNS之后的負載均衡承擔了服務地址翻譯的一部分能力,但是隨著微服務的流向 服務的非正常掉線、重啟、上下線越來越頻繁,zk曾經活躍過,但是過于底層,需要用戶自己做很多額外作業,因此專用于服務發現的 eureka出現并被納入spring cloud,后來就是Consul和nacos繼承了eureka的衣缽,
如何在基礎設定和網路協議層面,對應用盡可能無感知、方便地實作服務發現是目前服務發現的一個發展方向
1.2 服務發現組件中CA和AP的抉擇
服務注冊中心非常關鍵, 一旦崩潰將不可使用,因此必須最大程度保證可用,例如搞多個注冊中心節點提供服務,不斷復制各自的資訊,隨時提供服務,
但是復制資訊又要即時回應的程序會造成結果的不一致,缺乏一致性,
- Eureka優先保證可用性,犧牲一致性, 選擇異步復制來交換服務注冊資訊,同時并不會強行等待復制成功,有新服務注冊對應節點可立刻宣布該服務,適合節點關系相對固定, 服務一般不會頻繁上下線的系統,
- Consul是優先保證一致性,犧牲可用性,使用Raft演算法,要求多數節點寫入成功后服務的注冊才算完成,嚴格保證了一致性,同時采用gossip協議,支持多個資料中心逐漸的服務同步,
選擇哪個方案,一定程度上是基于產品現實而做的決策,當系統C因為網路問題,變成了A\B兩個磁區后,是否對你的服務有重大影響?是否是有狀態的系統? 如果是,那么選擇對一致性嚴格要求的Consul,如果不是,則選擇Eureka,
1.3 注冊中心的實作
在分布式KV存盤框架上單獨做的服務發現
典型代表: zk、 etcd,etcd采用Raft演算法,zk采用的zab演算法是MultiPaxos的派生演算法,
共同特點是在整體較高復雜度的架構和演算法的外部,維持著極為簡單的應用介面,只有少量CRUD和watch的api, 所以要實作完整的服務發現,要做很大量的作業,只有自研大廠才會這么做,小廠不會首選耗費大量人力去從零實作,
基礎設施實作服務發現
典型代表是k8s里用的skyDNS、 coreDNS,作業原理是從API-server中監聽集群服務變化,根據服務生產DNS記錄存到etcd中, k8s設定每個pos的dns服務地址, 呼叫服務時再做域名轉換,
是CP還是AP取決于后端如何存盤,用etcd就是CP,用記憶體賦值就是AP,好處是對應用透明,只依賴底層的HTTP和DNS,不依賴語言等,缺點是要自己額外做負載均衡、遠程呼叫、服務快取期限各種能力適配
專門用于服務發現的框架和工具
典型代表: Eureka、Consul、Nacos,
壞處在于對應用不是透明的,必須在應用中要去適配服務注冊框架,但能夠為編碼開發、快速擴展能力提供方便,
2 網關路由
2.1 網關的職責
微服務網關的首要職責就是作為統一的出口對外提供服務, 將外部訪問網關地址的流量,根據適當的規則路由到內部集群中正確的服務節點上,同時再作為流量過濾器增強使用
因此“網關= 路由器(基礎職能)+ 過濾器(可選職能)”
網關的性能主要取決于他們如何處理代理網路請求,也就是他們的網路IO模型
2.2 網路IO模型介紹
同步和異步的區別, 是指呼叫端發出請求后,是否需要一直等待,是否會銅鼓哦狀態變化和回呼來通知矗立著,
阻塞和非阻塞是針對請求處理程序而言,呼叫請求回傳結果之前,處理執行緒是否會被掛起,
阻塞IO、非阻塞IO、 多路復用、信號驅動IO都屬于同步IO,
- 阻塞IO是發現結果沒回傳,會掛起執行緒,直到結果回傳,
- 非阻塞IO是會不斷輪詢詢問是否完成、
- 多路復用IO是阻塞IO的一種,但他只有一個監聽執行緒在阻塞, 當有某個事件結果回傳,再進行對應處理,
- 信號驅動IO和異步IO有點像, 但是異步IO是資料已經被傳回到呼叫方了,然后通知, 而信號驅動IO只通知完成了,但是資料還要呼叫方重新阻塞式地去獲取,
Linux系統下實作高并發編程時仍以多路復用IO模型為主,
網關里, zuul1.0網關是用阻塞IO模型,碰到IO密集型就很浪費背景關系切換的性能, zuul2.0基于netty-server實作異步IO模型處理請求, 性能提升20%,可以自行指定 select、epoll等并發模型,
網關應該盡可能輕量、 成熟、 更成熟健壯的物理設施,
2.3 BFF網關
網關會針對不同的前端,聚合不同的服務,提供不同的介面和網路訪問協議支持(例如http和grpc都能提供)
3 客戶端負載均衡
用戶客戶端請求->某地域機房ip所在的服務網關->選擇發往對應業務服務所屬的負載均衡器->發給真正的服務
其中第三步的“發往業務服務負載均衡器”是有點浪費的, 從機房內網發出的服務請求, 繞道了網路邊緣的負載均衡器上了,又重新回了內網,
3.1 客戶端負載局衡器
就是在 機房網關->服務負載均衡器->服務節點的這個程序中, 去掉負載均衡器, 直接把負載均衡能力內置到機房網關的能力中,其他要用到負載均衡的場景也可以這樣操作不一定局限于網關,
優點:
- 負載均衡器和服務之間的資訊是行程內方法呼叫,不存在網路開銷
- 不依賴集群邊緣的設定,都是集群內部回圈
- 避免了負載局衡器的單點問題,
- 可以針對每個服務實體單獨設定負載均衡策略更靈活
缺點:
- 負載均衡代碼受限于服務本身代碼實作, 如果是go、python等會導致不得不適配多份負載均衡代碼
- 負載均衡器會占用服務的一部分資源或者互相影響
- 當服務被攻破, 下游所有節點的資訊也暴露,信任關系不安全
- 經常要輪詢、上線、下線,負擔不小
3.2 代理負載均衡器
基于k8s、docker部署的服務, 一般都有一個pod, 選擇在pod的邊緣部署一個代理負載均衡器(也叫邊車代理),相當于是同一個節點內,部署了一個行程,是服務網格的一個概念,
好處
- 不再受語言限制
- 避免服務行程要頻繁輪詢造成浪費, 直接讓控制平面給pod的邊車代理
- 更安全也更容易實作對呼叫鏈路的詳細統計,
3.3 地域和區域
region是地域的概念,
集群內部流量不會跨地域,
zone是區域的概念, 地理上是同一個地域,但是地域內可能放了不同的機房,每個大機房就是一個區域,
如果追求高可用,則系統要部署在多個區域中,
如果追去低延遲, 則應該所有服務都在同一個區域中,
相關思考
本文講了關于服務發現的很多干貨內容,核心內容為服務發現組件的選擇、網關的介紹、 客戶端側如何發給已發現的服務,如果準備進行服務發現的選型作業,可以仔細閱讀原文進行學習和了解,
文中關于注冊中心的實作原理有很多種型別, 其中有提到一個k8s里用的 coreDNS,那部分筆記中關于coreDns的原理 比較少,而華為云的CCE容器引擎就包含了CoreDNS插件,他們的產品資料中給出的路由請求流程如下:
另外對于專門用于服務發現的框架和工具,華為云的CSE微服務引擎里關于服務注冊發現的示意圖如下:
微服務啟動時,將實體資訊注冊到CSE,微服務需要呼叫其他微服務的介面時,從CSE查詢實體資訊,并將實體資訊快取到本地,快取會通過事件通知、定時查詢等機制更新;通過本地快取的地址資訊,實作微服務之間的點到點呼叫,
同時也支持基于上述提到的3個服務發現代表,實作優化上下線的能力:
點擊關注,第一時間了解華為云新鮮技術~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/551821.html
標籤:其他
下一篇:返回列表
