服務發現
什麼是服務發現
在傳統的系統部署中,服務運行在一個固定的已知的 IP 和埠上,如果一個服務需要調用另外一個服務,可以通過地址直接調用,但是,在虛擬化或容器話的環境中,服務實例的啟動和銷毀是很頻繁的,服務地址在動態的變化,如果需要將請求發送到動態變化的服務實例上,至少需要兩個步驟:
服務註冊 — 存儲服務的主機和埠信息
服務發現 — 允許其他用戶發現服務註冊階段存儲的信息
服務發現的主要優點是可以無需了解架構的部署拓撲環境,只通過服務的名字就能夠使用服務,提供了一種服務發布與查找的協調機制。服務發現除了提供服務註冊、目錄和查找三大關鍵特性,還需要能夠提供健康監控、多種查詢、實時更新和高可用性等。
有兩種主要的服務發現方式:客戶端發現(client-side service discovery)和服務端發現(server-side discovery)
客戶端服務發現
在使用客戶端發現方式時,客戶端通過查詢服務註冊中心,獲取可用的服務的實際網路地址(IP 和埠)。然後通過負載均衡演算法來選擇一個可用的服務實例,並將請求發送至該服務。優點:架構簡單,擴展靈活,方便實現負載均衡功能,缺點:強耦合,有一定開發成本。
服務端服務發現
客戶端向load balancer 發送請求。load balancer 查詢服務註冊中心找到可用的服務,然後轉發請求到該服務上。和客戶端發現一樣,服務都要到註冊中心進行服務註冊和註銷。優點:服務的發現邏輯對客戶端是透明的。缺點:需要額外部署和維護高可用的負載均衡器。
服務註冊中心
服務註冊中心是服務發現的核心。它保存了各個可用服務實例的網路地址(IP Address 和Port)。服務註冊中心必須要有高可用性和實時更新功能。有兩種不同的方式來處理服務的註冊和註銷。一種是服務自己主動註冊-自己註冊。另一種是通過其他組件來管理服務的註冊-第三方註冊。
自己註冊
使用 Self-Registration 的方式註冊,服務實例必須自己主動的到註冊中心註冊和註銷。比如可以使用 heartbeat 機制了實現。優點,非常簡單,不需要任何其它輔助組件。缺點:各個服務和註冊中心的耦合度比較高。
第三方註冊
服務本身不必關心註冊和註銷功能。而是通過其他組件來實現服務註冊功能。可以通過如事件訂閱等方式來監控服務的狀態,如果發現一個新的服務實例運行,就向註冊中心註冊該服務,如果監控到某一服務停止了,就向註冊中心註銷該服務。
常見的服務發現框架
常見服務發現框架 Consul、 ZooKeeper以及Etcd
ZooKeeper 是這種類型的項目中歷史最悠久的之一,它起源於 Hadoop。它非常成熟、可靠,被許多大公司(YouTube、eBay、雅虎等)使用。
Etcd是一個採用 HTTP 協議的健/值對存儲系統,它是一個分散式和功能層次配置系統,可用於構建服務發現系統。其很容易部署、安裝和使用,提供了可靠的數據持久化特性。搭配一些第三方工具,etcd(健/值對存儲系統)+ Registrator(服務註冊器) + Confd(輕量級的配置管理工具)
Consul 是強一致性的數據存儲,使用 Gossip 形成動態集群。它提供分級鍵/值存儲方式,不僅可以存儲數據,而且可以用於註冊器件事各種任務,從發送數據改變通知到運行健康檢查和自定義命令
Consul 介紹
Consul 是一個支持多數據中心分散式高可用的服務發現和配置共享的服務軟體,Consul 支持健康檢查,並允許 HTTP 和 DNS 協議調用 API 存儲鍵值對。一致性協議採用 Raft 演算法,用來保證服務的高可用。使用 Gossip 協議管理成員和廣播消息。
服務發現
Consul 的某些客戶端可以提供一個服務,其它客戶端可以使用 Consul 去發現這個服務的提供者,可以使用 DNS 或者 HTTP。
故障檢測
通過健康檢查,服務發現可以防止請求被路由到不健康的主機,並且可以使服務容易斷開(不再提供服務),如服務是否返回 200 OK、內存使用率是否在 90% 以下。
多數據中心
Consul 不需要複雜的配置即可簡便的擴展到多個數據中心,查找其它數據中心的服務或者只請求當前數據中心的服務。
鍵值存儲
靈活的鍵值存儲,提供動態配置、特徵標記、協作、Leader 選舉等功能,通過長輪詢實現配置改變的即時通知。
Agent - Agent 是在 Consul 集群的每個成員之上長期運行的一個守護進程, 是 Consul 的核心進。Agent 必須運行。Agent 可以運行在 Server 模式或者 Client 模式,由於所有的節點都必須運行一個 Agent,所有的節點都可以運行 DNS 和 HTTP 介面,以及負責運行健康檢查和保持服務同步。
Server - Server 是具備一組擴展職責的 Agent,包括:參與 Raft 法定人數,維護集群狀態,響應 RPC 請求,與其它數據中心交換廣域網流言,以及轉發請求到 Leader 或者遠程數據中心。每一個數據中心至少要有一個 Server,推薦要有3-5個 Server。
Client - Client 是轉發所有 RPC 到 Server 節點的 Agent。Client 是一個非常輕量級的進程,用來註冊服務,運行健康檢查,以及轉發查詢到 Server。Client 是相對無狀態的。Client 執行的唯一的後台活動是參與區域網的流言池。這隻有一個很小的資源開銷,並且只消耗少量的網路帶寬。
Raft 演算法
一致性協議採用 Raft 演算法,一致性(Consensus),它是指多個伺服器在狀態達成一致,但是在一個分散式系統中,因為各種意外可能,有的伺服器可能會崩潰或變得不可靠,它就不能和其他伺服器達成一致狀態。這樣就需要一種 Consensus 協議,一致性協議是為了確保容錯性,也就是即使系統中有一兩個伺服器當機,也不會影響其處理過程。
為了以容錯方式達成一致,我們不可能要求所有伺服器 100% 都達成一致狀態,只要超過半數的大多數伺服器達成一致就可以了,假設有 N 台伺服器,N/2 +1 就超過半數,代表大多數了。
在 Raft 中,任何時候一個伺服器可以扮演下面角色之一:
Leader: 處理所有客戶端交互,日誌複製等,一般一次只有一個 Leader.
Follower: 選民,完全被動
Candidate: 可以被選為一個新的領導人。
Raft 階段分為兩個,首先是選舉過程,然後在選舉出來的領導人帶領進行正常操作,比如日誌複製等。
選舉過程
任何一個節點都可以成為 Candidate,Follower 會等待一個隨機時間 election timeout (150ms-300ms) 後成為 Candidate, Candidate 會向其他節點發送選舉請求,其他節點會回復這個請求,當絕大多數節點同意時,Candidate 成為 Leader,如果在這個過程中,有一個 Follower 宕機,沒有收到請求選舉的要求,Candidate 可以自己選自己,只要達到 N/2 + 1 的大多數票,Candidate 還是可以成為 Leader的。
如果同時有兩個候選人向大家邀票,這時通過類似加時賽來解決,兩個候選者在一段 timeout比如 300ms 互相不服氣的等待以後,因為雙方得到的票數是一樣的,一半對一半,那麼在300ms 以後,再由這兩個候選者發出邀票,這時同時的概率大大降低,那麼首先發出邀票的的候選者得到了大多數同意,成為領導者 Leader,而另外一個候選者後來發出邀票時,那些Follower 選民已經投票給第一個候選者,不能再投票給它,它就成為落選者了,最後這個落選者也成為普通 Follower 一員了。
當一個 Leader 產生之後,它可以向選民也就是 Follower 們發出指令,比如進行日誌複製。
Raft 協議強依賴 Leader 節點的可用性來確保集群數據的一致性。當 Leader 產生之後,所有的更改都會通過 Leader,比如客戶端發出一個更改,Leader 會將這個更改寫入日誌中,並通過心跳向 Follower 們發出一個日誌複製的指令,當 Follow 將日誌寫入磁碟之後會發出一個response,當 Leader 收到絕大多數 response 則認為這個更改被提交,並會在下一個心跳的時候,通知所有 Follow 進行更新。
Raft 協議過程可參看動畫:http://thesecretlivesofdata.com/raft/
Gossip協議
當一個Consul Agent 啟動後,它沒有任何其它節點的知識:它是一個孤立的集群。想了解其它的集群成員,Agent 必須加入一個已經存在的集群。要加入已經存在的集群,它只需要知道一個已經存在的成員。Agent 加入後,它將通過流言協議和這個成員進行交流,並很快的發現集群中的其它成員。Consul Agent 可以加入任何一個其它的 Agent,不只是 Server 模式的Agent。
Gossip 是一個點對點的通信協議,在這個協議中,節點之間定期交換狀態信息。Gossip 協議每隔一秒運行一次,節點和不超過的三個節點交換信息,因此所有的節點能夠很快知道集群中其他節點的信息。每一個 gossip 信息有一個版本,因此在信息的交換中,舊的信息會被新的狀態信息覆蓋。
首先要傳播謠言就要有種子節點。種子節點每秒都會隨機向其他節點發送自己所擁有的節點列表,以及需要傳播的消息。任何新加入的節點,就在這種傳播方式下很快地被全網所知道。
1. SYN: 節點 A 隨機選擇一些節點,這裡可以只選擇發送摘要,即不發送value,避免消息過大。
2. ACK: 節點 B 接收到消息後,會將其與本地的合併,這裡合併採用的是對比版本,版本較大的說明數據較新。
比如節點 A 向節點 B 發送數據 C (key, value, 2),而節點 B 本機存儲的是 C (key, value1, 3),那麼因為 B 的版本比較新,合併之後的數據就是B本機存儲的數據,然後會發回 A 節點。3. ACK2: 節點 A 接收到 ACK 消息,將其應用到本機的數據中。
下圖是對Gossip協議收斂情況的模擬
Gossip interval:0.2 秒
節點數:30 nodes
gossip fanout:3 nodes
參考文獻
1. 微服務系統中的服務發現機制
http://www.jianshu.com/p/ece3e0ffc70c2. Consul 源碼地址https://github.com/hashicorp/consul
3. Consul 可執行文件地址https://www.consul.io/downloads.html
4. Consul 官方地址https://www.consul.io/
5. Consul 官方演示http://demo.consul.io/ui/
6. 服務發現系統Consul介紹http://www.codeweblog.com/%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0%E7%B3%BB%E7%BB%9Fconsul%E4%BB%8B%E7%BB%8D/
7. Consul 原理和使用簡介https://blog.coding.net/blog/intro-consul?type=hot
8. Consul 修鍊http://blog.csdn.net/column/details/consul.html
9. Consul 調研http://blog.csdn.net/younger_china/article/details/52243700
10. 分散式系統的Raft演算法http://www.jdon.com/artichect/raft.html
11. Raft 動畫http://thesecretlivesofdata.com/raft/
12. Raft 一致性演算法http://blog.csdn.net/cszhouwei/article/details/38374603
13. Raft 為什麼是更易理解的分散式一致性演算法https://www.cnblogs.com/mindwind/p/5231986.html
14. 節點間通信協議之gossip協議https://www.cnblogs.com/dyf6372/p/3528193.html
15. Cassandra 學習筆記之 Gossip 協議
http://blog.csdn.net/aesop_wubo/article/details/20401431
16. Consul 集群架構http://blog.csdn.net/maoyeqiu/article/details/77478732
17. 初識服務發現及Consul框架的簡單使用 https://www.cnblogs.com/newP/p/6349316.html
18. Consul 的整體架構 http://blog.csdn.net/u012422829/article/details/77887753
19. 服務發現:Zookeeper vs etcd vs Consul http://dockone.io/article/667
20. 搭建 Consul 集群 https://www.cnblogs.com/shanyou/p/6286207.html
21. Gossip 演算法 http://blog.csdn.net/chen77716/article/details/6275762
22. 分散式系統協調 http://www.cnblogs.com/shanyou/p/4714838.html
23. Gossip 協議實現 https://segmentfault.com/a/1190000010635808
推薦閱讀:
※THE2018世界大學計算機科學專業Top100排行榜
※2017工作小感
※我開了一個專欄
※中美兩位 AI 大師的「巔峰對話」:為何 NLP 領域難以出現「獨角獸」? | 獨家
※烷烴同分異構體個數的計數方法
TAG:計算機科學 |