微信公衆號:內核小王子 關注可瞭解更多關於數據庫,JVM內核相關的知識; 若是你有任何疑問也能夠加我pigpdong[^1]html
爲何須要服務註冊中心? 隨着服務數量的擴張,咱們須要服務調用方可以自動感知到服務提供方的地址,當咱們對服務提供方進行橫向擴展的時候,服務調用方可以自動感知到,這就須要服務提供方可以在啓動或者關閉的時候自動向註冊中心註冊,而服務調用方直接詢問註冊中心就能夠知道具體的服務提供方的地址列表,服務調用方能夠本身根據特定的路由算法作負載均衡, 或者服務調用方根本不須要知道服務提供方的具體地址,統一發給一個代理系統,由這個代理系統轉發給對應的服務調用方。因此爲了支持服務的彈性擴展,咱們須要一個獨立系統作服務發現和負載均衡,目前作服務發現有三種代理模式nginx
集中代理模式通常是在服務調用方和服務提供方之間部署一套獨立的代理系統來接收調用方的請求,而後配合域名系統和特定的負載均衡策略以及路由算法,轉發到對應的服務提供方,這個代理系統通常由硬件F5設備加7層軟件負載nginx配合域名系統來使用,這種模式,有集中治理,運維簡單,並且和語言棧無關的優勢,可是目前這個代理系統存在單點問題,並且配置比較麻煩,因爲服務調用者沒有之間調用服務提供方,因此網絡上存在多一跳的開銷,目前國內主要有攜程等公司在使用算法
目前不少公司用springcloud或者dubbo做爲rpc框架的公司多選擇這種模式,在客戶端嵌入一個程序作服務發現和軟件負載均衡,調用方會緩存服務提供方的地址列表,而且本身根據路由算法和負載均衡策略選擇服務提供者進行調用,這種模式須要一個第三方的註冊中心配合,服務提供者啓動的時候將服務註冊到註冊中心,服務調用方去註冊中心獲取服務提供者信息,這種模式有無單點問題,性能好的優勢,可是因爲客戶端須要關心負載均衡和維護提供者列表,致使客戶端臃腫,目前國內主要有阿里的dubbo和新浪的Motanspring
這種模式是前面兩種模式的一個折中,將這個代理放到主機的一個獨立程序上,全部這個主機上的應用共享這個代理,應用通常部署在docker容器中,主機能夠是一個物理機也能夠是虛擬機。在這個代理上進行路由和負載均衡,這個模式也須要一個模式二中獨立的註冊中心來輔助代理程序作服務發現,這種模式兼具上面兩種模式的優勢,可是運維較複雜,目前國內只有惟品會有這種模式的探索docker
邊車模式,sidecar,將一個單獨的進程用來處理,日誌,健康,限流,服務發現等功能,和應用層徹底分離,目前若是咱們大多lib等軟件包的形式和應用集成來實現限流和監控,這樣增長了應用依賴,每次lIB包升級都須要將應用從新編譯發佈,而邊車模式下咱們能夠將邏輯層和控制層分開部署.數據庫
邊車模式進化後,將這個獨立程序集羣化,就成了servicemesh,也就是CNCF所推薦的新一代微服務架構,將這個代理程序下沉爲一個基礎服務,做爲平臺開放給應用程序編程
servicemesh的定義:一做爲個輕量級的網絡代理專職處理服務和服務間的通信,對應用程序透明,用來分離或者解耦和分佈式系統架構中控制層的上的東西.緩存
相似於網絡七層模型中的TCP協議,將底層那些難控制的網絡通信方面的東西(擁塞控制,丟包重傳,流量控制)都處理了,而上層的http協議就只用關心應用層的html格式安全
演化路徑微信
目前開源的servicemesh實現有istio
註冊中心提供了兩個服務,一個是讓服務提供方註冊,就是寫數據,另外一個是讓服務調用方查詢,就是讀數據,當註冊中心集羣部署後,每一個節點 均可以對外提供讀寫服務,每一次寫請求都會同步到其餘節點,這樣才能讓其餘節點提供的讀服務正確,若是節點之間的數據複製出現不一致,那麼將致使服務調用方獲取到的服務提供者列表中要麼出現已經下線的節點,要麼少提供了一個正常的節點, 提供了下線的節點,服務調用者能夠經過重試機制調用其餘節點,出現少提供一個正常節點則致使服務提供方的流量不均勻,這些都是能夠接受的,況且各個節點最終都會同步成功,也就是數據最終一致性,因此咱們但願註冊中心是高可用的,最好能知足最終一致性,而zookeeper是典型的CP設計,在網絡分區狀況下不可用,當節點超過半數掛掉不可用,違背了註冊中心不能由於自身任何緣由破壞服務自己的可連通性
咱們看下下圖zookeeper三機房5節點部署的狀況下,若是機房3和機房1機房2網絡出現分區成爲孤島,zookeeper和機房3裏的其餘應用不能和外部通訊,zookeeper因爲聯繫不是leader將不可用,雖然zookeeper整個集羣中其餘4個節點依然能夠對外提供服務,可是zookeeper爲了保證在腦裂的狀況下數據一致性,機房3的節點5將不能進行讀寫服務,這個時候機房3內的應用A雖然不能 調用其餘機房的服務B可是能夠調用機房3內的服務B,可是因爲Zookeeper5不能讀寫,因此機房內也不能讀寫,這對應用來講是徹底不能接受的,咱們有時候爲了性能考慮還好主動修改路由策略讓應用盡可能同機房調用,試想一下若是三個機房都出現網絡分區相互成爲孤島,那麼整個應用將不可用
[圖片上傳失敗...(image-269105-1558422945065)]
zookeeper須要和全部的服務保持長鏈接,而隨着服務的頻繁發佈,以及服務的健康檢查,會致使zookeeper壓力愈來愈大,而zookeeper並不能經過橫向擴展節點解決,能夠提供的方案是按照業務進行拆分到不一樣的zookeeper集羣
服務提供方是否可用,不能僅僅經過zookeeper的session是否存活判斷,TCP活性並不能反映服務的真實健康狀態,而須要完整的健康體系,CPU,內存,服務是否可用,數據庫是否能聯通等
指標 | Consule | zookeeper | etcd | eureka |
---|---|---|---|---|
服務監控檢測 | 服務狀態,內存,硬盤 | 長鏈接keepalived | 鏈接心跳 | 須要配置 |
多數據中心 | 支持 | 不支持 | 不支持 | 不支持 |
KV存儲 | 支持 | 支持 | 支持 | 不支持 |
一致性 | gossip | paxos | raft | 無 |
CAP | CA | CP | CP | AP |
使用接口(多語言能力) | 支持http和dns | 客戶端 | http/grpc | http(sidecar) |
watch支持 | 全量/支持long polling | 支持 | 支持 long polling | 支持 long polling/大部分增量 |
自身監控 | metrics | — | metrics | metrics |
安全 | acl /https | acl | https支持(弱) | — |
spring cloud集成 | 已支持 | 已支持 | 已支持 | 已支持 |