此圖是官網提供的一個事例系統圖,圖中的Server是consul服務端高可用集群,Client是consul客戶
端。consul客戶端不保存數據,客戶端將接收到的請求轉發給響應的Server端。Server之間通過局域網
或廣域網通信實現數據一致性。每個Server或Client都是一個consul agent。Consul集群間使用了
GOSSIP協議通信和raft一致性算法。上面這張圖涉及到了很多術語:
Agent——agent是一直運行在Consul集群中每個成員上的守護進程。通過運行 consul agent來啟動。
agent可以運行在client或者server模式。指定節點作為client或者server是非常簡單的,除非有其
他agent實例。所有的agent都能運行DNS或者HTTP接口,並負責運行時檢查和保持服務同步。
Client——一個Client是一個轉發所有RPC到server的代理。這個client是相對無狀態的。client唯
一執行的后台活動是加入LAN.
gossip池——這有一個最低的資源開銷並且僅消耗少量的網絡帶寬。
Server——一個server是一個有一組擴展功能的代理,這些功能包括參與Raft選舉,維護集群狀
態,響應RPC查詢,與其他數據中心交互WANgossip和轉發查詢給leader或者遠程數據中心。
DataCenter——雖然數據中心的定義是顯而易見的,但是有一些細微的細節必須考慮。例如,在
EC2中,多個可用區域被認為組成一個數據中心?我們定義數據中心為一個私有的,低延遲和高帶
寬的一個網絡環境。這不包括訪問公共網絡,但是對於我們而言,同一個EC2中的多個可用區域可
以被認為是一個數據中心的一部分。
Consensus——在我們的文檔中,我們使用Consensus來表明就leader選舉和事務的順序達成一
致。由於這些事務都被應用到有限狀態機上,Consensus暗示復制狀態機的一致性。
Gossip——Consul建立在Serf的基礎之上,它提供了一個用於多播目的的完整的gossip協議。
Serf提供成員關系,故障檢測和事件廣播。更多的信息在gossip文檔中描述。這足以知道gossip使
用基於UDP的隨機的點到點通信。
LAN Gossip——它包含所有位於同一個局域網或者數據中心的所有節點。 WAN
Gossip——它只包含Server。這些server主要分布在不同的數據中心並且通常通過因特網或者廣
域網通信。
在每個數據中心,client和server是混合的。一般建議有3-5台server。這是基於有故障情況下的可用性
和性能之間的權衡結果,因為越多的機器加入達成共識越慢。然而,並不限制client的數量,它們可以
很容易的擴展到數千或者數萬台。
同一個數據中心的所有節點都必須加入gossip協議。這意味着gossip協議包含一個給定數據中心的所有
節點。這服務於幾個目的:第一,不需要在client上配置server地址。發現都是自動完成的。第二,檢
測節點故障的工作不是放在server上,而是分布式的。這是的故障檢測相比心跳機制有更高的可擴展
性。第三:它用來作為一個消息層來通知事件,比如leader選舉發生時。
每個數據中心的server都是Raft節點集合的一部分。這意味着它們一起工作並選出一個leader,一個有
額外工作的server。leader負責處理所有的查詢和事務。作為一致性協議的一部分,事務也必須被復制
到所有其他的節點。因為這一要求,當一個非leader得server收到一個RPC請求時,它將請求轉發給集
群leader。
server節點也作為WAN gossip Pool的一部分。這個Pool不同於LAN Pool,因為它是為了優化互聯網更
高的延遲,並且它只包含其他Consul server節點。這個Pool的目的是為了允許數據中心能夠以low-
touch的方式發現彼此。這使得一個新的數據中心可以很容易的加入現存的WAN gossip。因為server都
運行在這個pool中,它也支持跨數據中心請求。當一個server收到來自另一個數據中心的請求時,它隨
即轉發給正確數據中想一個server。該server再轉發給本地leader。
這使得數據中心之間只有一個很低的耦合,但是由於故障檢測,連接緩存和復用,跨數據中心的請求都
是相對快速和可靠的。
Consul的核心知識
Gossip協議
傳統的監控,如ceilometer,由於每個節點都會向server報告狀態,隨着節點數量的增加server的壓力
隨之增大。在所有的Agent之間(包括服務器模式和普通模式)運行着Gossip協議。服務器節點和普通
Agent都會加入這個Gossip集群,收發Gossip消息。每隔一段時間,每個節點都會隨機選擇幾個節點發
送Gossip消息,其他節點會再次隨機選擇其他幾個節點接力發送消息。這樣一段時間過后,整個集群都
能收到這條消息。示意圖如下。
RAFT一致性算法
為了實現集群中多個ConsulServer中的數據保持一致性,consul使用了基於強一致性的RAFT算法。
在Raft中,任何時候一個服務器可以扮演下面角色之一:
1. Leader: 處理所有客戶端交互,日志復制等,一般一次只有一個Leader.
2. Follower: 類似選民,完全被動
3. Candidate(候選人): 可以被選為一個新的領導人。
Leader全權負責所有客戶端的請求,以及將數據同步到Follower中(同一時刻系統中只存在一個
Leader)。Follower被動響應請求RPC,從不主動發起請求RPC。Candidate由Follower向Leader轉換的中間狀態
關於RAFT一致性算法有一個經典的動畫http://thesecretlivesofdata.com/raft/,其中詳細介紹了選
舉,數據同步的步驟。
Consul 集群搭建
首先需要有一個正常的Consul集群,有Server,有Leader。這里在服務器Server1、Server2、Server3
上分別部署了Consul Server。(這些服務器上最好只部署Consul程序,以盡量維護Consul Server的穩定)
服務器Server4和Server5上通過Consul Client分別注冊Service A、B、C,這里每個Service分別部署在
了兩個服務器上,這樣可以避免Service的單點問題。(一般微服務和Client綁定)
在服務器Server6中Program D需要訪問Service B,這時候Program D首先訪問本機Consul Client提供
的HTTP API,本機Client會將請求轉發到Consul Server,Consul Server查詢到Service B當前的信息返回
Agent 以 client 模式啟動的節點。在該模式下,該節點會采集相關信息,通過 RPC 的方式向
server 發送。Client模式節點有無數個,官方建議搭配微服務配置
Agent 以 server 模式啟動的節點。一個數據中心中至少包含 1 個 server 節點。不過官方建議使用
3 或 5 個 server 節點組建成集群,以保證高可用且不失效率。server 節點參與 Raft、維護會員信
息、注冊服務、健康檢查等功能。
安裝consul並啟動
在每個consul節點上安裝consul服務,下載安裝過程和單節點一致。
#從官網下載最新版本的Consul服務
wget https://releases.hashicorp.com/consul/1.5.3/consul_1.5.3_linux_amd64.zip
##使用unzip命令解壓
unzip consul_1.5.3_linux_amd64.zip
##將解壓好的consul可執行命令拷貝到/usr/local/bin目錄下
cp consul /usr/local/bin
##測試一下
consul
##登錄s1虛擬機,以server形式運行
consul agent -server -bootstrap-expect 3 -data-dir /etc/consul.d -node=server-1
-bind=192.168.74.101 -ui -client 0.0.0.0 &
##登錄s2 虛擬機,以server形式運行
consul agent -server -bootstrap-expect 2 -data-dir /etc/consul.d -node=server-2
-bind=192.168.74.102 -ui -client 0.0.0.0 &
##登錄s3 虛擬機,以server形式運行
consul agent -server -bootstrap-expect 2 -data-dir /etc/consul.d -node=server-3
-bind=192.168.74.103 -ui -client 0.0.0.0 &
-server: 以server身份啟動。
-bootstrap-expect:集群要求的最少server數量,當低於這個數量,集群即失效。
-data-dir:data存放的目錄,更多信息請參閱consul數據同步機制
-node:節點id,在同一集群不能重復。
-bind:監聽的ip地址。
-client:客戶端的ip地址(0.0.0.0表示不限制)
& :在后台運行,此為linux腳本語法
##在本地電腦中使用client形式啟動consul
consul agent -client=0.0.0.0 -data-dir /etc/consul.d -node=client-1
每個節點加入集群
在s2,s3,s4 服務其上通過consul join 命令加入 s1中的consul集群中
##加入consul集群
consul join 192.168.74.101
測試
在任意一台服務器中輸入 consul members查看集群中的所有節點信息
##查看consul集群節點信息
consul members
注:由於我阿里雲部署每個節點都加不進去,這里就不演示了,把部署的過程直接貼出來。