上一篇提到姐叁,項(xiàng)目用的分布式服務(wù)發(fā)現(xiàn)與注冊(cè)組件是consul铅乡,這篇文章主要來講下consul組件在項(xiàng)目中的應(yīng)用以及相關(guān)介紹疗锐。本文以官方文檔為主要參考consul文檔。
1. consul介紹
consul是一個(gè)服務(wù)管理軟件篓吁,主要功能如下:
- 支持多數(shù)據(jù)中心下,分布式高可用的蚪拦,服務(wù)發(fā)現(xiàn)和配置共享杖剪。
- consul支持健康檢查,允許存儲(chǔ)鍵值對(duì)驰贷。
- 一致性協(xié)議采用
Raft
算法,用來保證服務(wù)的高可用盛嘿。 - 成員管理和消息廣播采用
GOSSIP
協(xié)議,支持ACL訪問控制括袒。
1.1 服務(wù)注冊(cè)與發(fā)現(xiàn)
服務(wù)注冊(cè)是一個(gè)服務(wù)將其位置信息在“中心注冊(cè)節(jié)點(diǎn)”注冊(cè)的過程次兆。該服務(wù)一般會(huì)將它的主機(jī)IP地址以及端口號(hào)進(jìn)行注冊(cè),有時(shí)也會(huì)有服務(wù)訪問的認(rèn)證信息锹锰,使用協(xié)議芥炭,版本號(hào)漓库,以及關(guān)于環(huán)境的一些細(xì)節(jié)信息。
而服務(wù)發(fā)現(xiàn)可以讓一個(gè)應(yīng)用或者組件發(fā)現(xiàn)其運(yùn)行環(huán)境以及其它應(yīng)用或組件的信息园蝠。用戶配置一個(gè)服務(wù)發(fā)現(xiàn)工具就可以將實(shí)際容器跟運(yùn)行配置分離開渺蒿。常見配置信息包括:ip、端口號(hào)彪薛、名稱等蘸嘶。
在傳統(tǒng)情況下,當(dāng)出現(xiàn)服務(wù)存在于多個(gè)主機(jī)節(jié)點(diǎn)上時(shí)陪汽,都會(huì)使用靜態(tài)配置的方法來實(shí)現(xiàn)服務(wù)信息的注冊(cè)训唱。
而當(dāng)在一個(gè)復(fù)雜的系統(tǒng)里,需要較強(qiáng)的可擴(kuò)展性時(shí)挚冤,服務(wù)被頻繁替換時(shí)况增,為避免服務(wù)中斷,動(dòng)態(tài)的服務(wù)注冊(cè)和發(fā)現(xiàn)就很重要训挡。
服務(wù)注冊(cè)與發(fā)現(xiàn)的組件有很多澳骤,如Zookeeper、Etcd等澜薄。既可用于服務(wù)間的協(xié)調(diào)为肮,同時(shí)又可用于服務(wù)的注冊(cè)。
1.2 Consensus Protocol - Raft
Consul使用Consensus協(xié)議Raft提供一致性(Consistency)肤京。本文只是簡(jiǎn)單介紹在consul中的一致性颊艳,后面專門一篇寫raft。
首先忘分,Raft是一種基于Paxos的Consensus算法棋枕。相比于Paxos,Raft設(shè)計(jì)采用了較少的狀態(tài)妒峦,并且是一種更簡(jiǎn)單重斑、更易于理解的算法。
只有Server節(jié)點(diǎn)參與Raft肯骇,且是peer set的一員窥浪。所有的Client節(jié)點(diǎn)只是轉(zhuǎn)發(fā)請(qǐng)求到Server。這種設(shè)計(jì)的考慮是笛丙,當(dāng)更多的成員加入到peer set中時(shí)漾脂,quorum的規(guī)模也會(huì)增加∪粽可能會(huì)導(dǎo)致性能問題是等待quorum個(gè)節(jié)點(diǎn)log entry符相。
啟動(dòng)Consul時(shí),單個(gè)consul節(jié)點(diǎn)需要以bootstrap模式運(yùn)行,該模式運(yùn)行自我選舉為leader啊终。一旦Leader被選出來镜豹,其他Server可以添加Peer set中,保持一致性和安全性蓝牲。最終一些Server添加到集群趟脂,bootstrap模式需要禁用。
因?yàn)樗蠸erver都是Peer set中的成員例衍,它們都知道誰是Leader昔期。當(dāng)一個(gè)RPC請(qǐng)求到達(dá)某個(gè)非Leader Server節(jié)點(diǎn),請(qǐng)求就會(huì)被轉(zhuǎn)發(fā)到Leader佛玄。如果RPC是一種query類型硼一,這意味著它是只讀的,Leader會(huì)基于FSM當(dāng)前生成相應(yīng)的結(jié)果梦抢,如果RPC是一種transaction類型般贼,即修改狀態(tài),Leader產(chǎn)生一個(gè)新的日志條目奥吩,并基于Raft算法進(jìn)行管理哼蛆。一旦日志條目應(yīng)用于有限狀態(tài)機(jī),transaction完成霞赫。
由于Raft的replication性質(zhì)腮介,性能對(duì)網(wǎng)絡(luò)延遲是非常敏感的。為此端衰,每個(gè)數(shù)據(jù)中心選擇獨(dú)立的Leader和維護(hù)一個(gè)不關(guān)聯(lián)的peer set叠洗。數(shù)據(jù)按照數(shù)據(jù)中心進(jìn)行劃分,所以每個(gè)Leader只負(fù)責(zé)在相應(yīng)數(shù)據(jù)中心的數(shù)據(jù)靴迫。當(dāng)接收到一個(gè)遠(yuǎn)程數(shù)據(jù)中心的請(qǐng)求時(shí)惕味,請(qǐng)求會(huì)被轉(zhuǎn)發(fā)到相應(yīng)的Leader楼誓。這種設(shè)計(jì)在不犧牲一致性的情況實(shí)現(xiàn)較低延遲交易和更高的可用性玉锌。
雖然所有日志副本的寫入都是基于Raft,讀取更靈活疟羹。但為了支持開發(fā)人員可能需要的各種權(quán)衡主守,Consul支持3種不同的一致性模式。
- Default榄融,Raft采用Leader租賃模式参淫,提供了一個(gè)時(shí)間窗口,在該時(shí)間段內(nèi)愧杯,Leader角色是穩(wěn)定的涎才。
- consistent,無條件一致性
- stale,這種模式允許在任何Server節(jié)點(diǎn)執(zhí)行讀取操作耍铜,無論它是不是Leader邑闺。
1.3 Group Membership Protocol - Gossip
Consul使用gossip協(xié)議管理成員關(guān)系、廣播消息到整個(gè)集群棕兼。詳情可參考Serf library陡舅。
Consul利用兩個(gè)不同的gossip pool。局域網(wǎng)(LAN Pool)和廣域網(wǎng)(WAN Pool)伴挚。
每個(gè)Consul數(shù)據(jù)中心都有一個(gè)包含所有成員(Server和Client)的LAN gossip pool靶衍。LAN Pool有如下幾個(gè)目的:
- 首先,成員關(guān)系允許Client自動(dòng)發(fā)現(xiàn)Server節(jié)點(diǎn)茎芋,減少所需的配置量颅眶。
- 其次,分布式故障檢測(cè)允許的故障檢測(cè)的工作在某幾個(gè)Server幾點(diǎn)執(zhí)行田弥,而不是集中整個(gè)集群所有節(jié)點(diǎn)上帚呼。
- 最后,gossip允許可靠和快速的事件廣播皱蹦,如Leader選舉煤杀。
WAN Pool是全局唯一的,無論屬于哪一個(gè)數(shù)據(jù)中心沪哺,所有Server應(yīng)該加入到WAN Pool沈自。由WAN Pool提供會(huì)員信息讓Server可節(jié)電執(zhí)行跨數(shù)據(jù)中心的請(qǐng)求。集成中故障檢測(cè)允許Consul妥善處理整個(gè)數(shù)據(jù)中心失去連接辜妓,或在遠(yuǎn)程數(shù)據(jù)中心只是單個(gè)的Server節(jié)點(diǎn)枯途。
所有這些功能都是通過利用Serf提供。從用戶角度來看籍滴,它是作為一個(gè)嵌入式庫(kù)提供這些功能酪夷。但其被Consul屏蔽,用戶無需關(guān)心孽惰。作為開發(fā)人員可以去了解這個(gè)庫(kù)是如何利用晚岭。
1.4 Session會(huì)話
上一篇文章snowflake升級(jí)版全局id生成中使用到了consul的KV存儲(chǔ)。
Consul提供session會(huì)話機(jī)制勋功,可以用于構(gòu)建分布式鎖坦报。session可以綁定到節(jié)點(diǎn)、健康檢查狂鞋、KV數(shù)據(jù)片择,目的是提供細(xì)粒度鎖。
KV存儲(chǔ)和會(huì)話的集成是使用會(huì)話的主要場(chǎng)景骚揍。必須在使用之前創(chuàng)建一個(gè)會(huì)話字管,然后使用它的ID。KV API支持acquire和release操作,acquire操作類似CAS操作嘲叔,只有當(dāng)鎖空閑時(shí)才會(huì)返回成功脐供。當(dāng)成功時(shí),某個(gè)normal標(biāo)識(shí)會(huì)更新借跪,也會(huì)遞增LockIndex政己,當(dāng)然也會(huì)更新session的信息。
如果在acquire操作時(shí)掏愁,與session相關(guān)的鎖已經(jīng)持有歇由,那么LockIndex就不會(huì)遞增,但是key值會(huì)更新果港,這就允許鎖的當(dāng)前持有者無需重新獲得鎖就可以更新key的內(nèi)容沦泌。
一旦獲得鎖,所需要經(jīng)release操作來釋放(使用相同的session)辛掠。Release操作也類似于CAS操作谢谦。如果給定的session無效,那么請(qǐng)求會(huì)失敗萝衩。需要特別注意的是回挽,無需經(jīng)過session的創(chuàng)建者,lock也是可以被釋放的猩谊。這種設(shè)計(jì)是允許操作者干預(yù)來終止會(huì)話千劈,在需要的時(shí)候。如上所述牌捷,會(huì)話無效也將導(dǎo)致所有被持有的鎖被釋放或刪除墙牌。當(dāng)鎖被釋放時(shí),LockIndex不會(huì)變化暗甥,但是session會(huì)被清空喜滨,并且ModifyIndex遞增。這些語義允許元組(Key撤防,LockIndex虽风,Session)作為一個(gè)獨(dú)特的“序列”。這個(gè)序列可以被傳遞和用于驗(yàn)證請(qǐng)求是否屬于當(dāng)前的鎖持有者即碗。因?yàn)槊看蝍cquire 都會(huì)導(dǎo)致LockIndex遞增焰情,即使同一會(huì)話中重新獲取鎖,該序列能夠檢測(cè)到陳舊的請(qǐng)求剥懒。同樣,如果會(huì)話失效合敦,相應(yīng)的LockIndex將為空初橘。
要清楚的是,這種鎖系統(tǒng)是純粹的咨詢。并不是強(qiáng)制Client必須獲取鎖再能執(zhí)行操作作保檐。任何客戶端都可以在未獲得鎖的情況下讀取耕蝉、寫入和刪除Key操作。它不是Consul用于保護(hù)系統(tǒng)的方法夜只。
2. consul架構(gòu)
上面介紹了consul的技術(shù)內(nèi)幕±菰冢現(xiàn)在來講講consul的架構(gòu)。
拆解開這個(gè)體系扔亥,從每一個(gè)組件開始了解场躯。首先,可以看到有兩個(gè)數(shù)據(jù)中心旅挤,分別標(biāo)記為“one”和“two”踢关。Consul是支持多數(shù)據(jù)中心一流,并且是常用業(yè)務(wù)場(chǎng)景粘茄。
每個(gè)數(shù)據(jù)中心都是由Server和client組成签舞。建議有3~5臺(tái)Server,基于故障處理和性能的平衡之策柒瓣。如果增加越多的機(jī)器儒搭,則Consensus會(huì)越來越慢。對(duì)client沒有限制芙贫,可以很容易地?cái)U(kuò)展到成千上萬或數(shù)萬师妙。
同一個(gè)數(shù)據(jù)中心的所有節(jié)點(diǎn)都要加入Gossip協(xié)議。這意味著gossip pool包含給定數(shù)據(jù)中心的所有節(jié)點(diǎn)屹培。有以下目的:首先默穴,沒有必要為client配置服務(wù)器地址參數(shù);發(fā)現(xiàn)是自動(dòng)完成的褪秀。第二蓄诽,節(jié)點(diǎn)故障檢測(cè)的工作不是放置在服務(wù)器上,而是分布式的媒吗。這使故障檢測(cè)比心跳機(jī)制更可擴(kuò)展性仑氛。第三,可用來作為消息層通知重要的事件闸英,如leader選舉锯岖。
每個(gè)數(shù)據(jù)中心的服務(wù)器都是屬于一個(gè)Raft peer。這意味著甫何,他們一起工作出吹,選出一個(gè)的Leader,Leader server是有額外的職責(zé)辙喂。負(fù)責(zé)處理所有的查詢和事務(wù)捶牢。事務(wù)也必須通過Consensus協(xié)議復(fù)制到所有的伙伴鸠珠。由于這一要求,當(dāng)非Leader Server接收到一個(gè)RPC請(qǐng)求秋麸,會(huì)轉(zhuǎn)發(fā)到集群的leader渐排。
Server節(jié)點(diǎn)也是作為WAN gossip pool的一部分。這個(gè)pool是與LAN gossip pool是不同的灸蟆,它為具有更高延遲的網(wǎng)絡(luò)響應(yīng)做了優(yōu)化驯耻,并且可能包括其他consul集群的server節(jié)點(diǎn)。設(shè)計(jì)WANpool的目的是讓數(shù)據(jù)中心能夠以low-touch的方式發(fā)現(xiàn)彼此炒考。將一個(gè)新的數(shù)據(jù)中心加入現(xiàn)有的WAN Gossip是很容易的可缚。因?yàn)槌刂械乃蠸erver都是可控制的,這也使跨數(shù)據(jù)中心的要求票腰。當(dāng)一個(gè)Serfer接收到不同的數(shù)據(jù)中心的要求時(shí)城看,它把這個(gè)請(qǐng)求轉(zhuǎn)發(fā)給相應(yīng)數(shù)據(jù)中心的任一Server。然后杏慰,接收到請(qǐng)求的Server可能會(huì)轉(zhuǎn)發(fā)給Leader测柠。
多個(gè)數(shù)據(jù)中心之間是低耦合,但由于故障檢測(cè)缘滥、連接緩存復(fù)用轰胁、跨數(shù)據(jù)中心要求快速和可靠的響應(yīng)。
3. consul部署
3.1 docker安裝
docker
安裝很簡(jiǎn)單朝扼,筆者這邊是基于docker-compose的配置文件赃阀,只需要本地安裝好docker和docker-compose,docker-compose.yml如下:
version: '3'
services:
consul:
image: consul
ports:
- "8500:8500"
- "8600:8600"
- "8300:8300"
拉取consul得最新image擎颖,進(jìn)行端口映射榛斯,暴露對(duì)外的端口8500,8300.
3.2 軟件安裝
- 從官網(wǎng)下載罪行的consul安裝包搂捧,https://www.consul.io/downloads.html驮俗。
- 解壓consul_0.6.4_darwin_amd64.zip。
- 將解壓后的二進(jìn)制文件consul拷貝到/usr/local/bin下允跑。
- 寫配置文件王凑。
服務(wù)注冊(cè)的配置文件如下:
{
"service": {
"name": "redis",
"tags": ["master"],
"address": "1192.168.1.100",
"port": 8000,
"enableTagOverride": false,
"check": {
"id": "redis",
"name": "redis on port 8000",
"tcp": "localhost:8000",
"interval": "10s",
"timeout": "1s"
}
}
}
如上配置注冊(cè)了Redis的8000端口,并帶有tcp的health check聋丝。
節(jié)點(diǎn)的配置文件:
{
"datacenter": "east-cn",
"data_dir": "/opt/consul",
"log_level": "INFO",
"node_name": "redis",
"server": true,
"addresses": {
"https": "192.168.1.100"
},
"ports": {
"https": 0
},
"ui": true,
"retry-join": [
]
}
當(dāng)加載配置選項(xiàng)時(shí)索烹,consul是按照詞典順序從所有配置文件或目錄中加載。比如弱睦,a.json
會(huì)先于e.json
處理百姓。后面設(shè)定的配置選項(xiàng)會(huì)合并到前面的配置集合中,如果存在重復(fù)的配置選項(xiàng)則會(huì)覆蓋每篷。當(dāng)然瓣戚,在某些情況下端圈,比如事件處理程序焦读,后面處理程序會(huì)追加到現(xiàn)有的配置選項(xiàng)中子库,形成事件處理程序列表。
3.3 啟動(dòng)
具體啟動(dòng)文檔見configuration矗晃。
如:
consul agent -server -config-dir /etc/consul.d -bind=192.168.1.100
-config-dir /etc/consul.d
config-dir
需要加載的配置文件目錄仑嗅,consul將加載目錄下所有后綴為“.json”的文件,加載順序?yàn)樽帜疙樞蛘胖ⅲ募信渲眠x項(xiàng)合并方式如config-file仓技。該參數(shù)可以多次配置。目錄中的子目錄是不會(huì)加載的俗他。data-dir
此目錄是為Agent存放state數(shù)據(jù)的脖捻。是所有Agent需要的,該目錄應(yīng)該存放在持久存儲(chǔ)中(reboot不會(huì)丟失)兆衅,對(duì)于server角色的Agent是很關(guān)鍵的地沮,需要記錄集群狀態(tài)。并且該目錄是支持文件鎖羡亩。server
設(shè)置Agent是server模式還是client模式摩疑。Consul agent有兩種運(yùn)行模式:Server和Client。這里的Server和Client只是Consul集群層面的區(qū)分畏铆,與搭建在Cluster之上 的應(yīng)用服務(wù)無關(guān)雷袋。Consule Server模式agent節(jié)點(diǎn)用于采用raft算法維護(hù)Consul集群的狀態(tài),官方建議每個(gè)Consul Cluster至少有3個(gè)或以上的運(yùn)行在Server mode的Agent辞居,Client節(jié)點(diǎn)不限楷怒。
其他常用的還有:
client
將綁定到client接口的地址,可以是HTTP瓦灶、DNS鸠删、RPC服務(wù)器。默認(rèn)為“127.0.0.1”,只允許回路連接倚搬。RPC地址會(huì)被其他的consul命令使用冶共,比如consul members,查詢agent列表node
節(jié)點(diǎn)在集群的名字,在集群中必須是唯一的每界。默認(rèn)為節(jié)點(diǎn)的Hostname捅僵。bootstrap
設(shè)置服務(wù)是否為“bootstrap”模式。如果數(shù)據(jù)中心只有1個(gè)server agent眨层,那么需要設(shè)置該參數(shù)庙楚。從技術(shù)上來講,處于bootstrap模式的服務(wù)器是可以選擇自己作為Raft Leader的趴樱。在consul集群中馒闷,只有一個(gè)節(jié)點(diǎn)可以配置該參數(shù)酪捡,如果有多個(gè)參數(shù)配置該參數(shù),那么難以保證一致性纳账。bind
用于集群內(nèi)部通信的IP地址逛薇,與集群中其他節(jié)點(diǎn)互連可通。默認(rèn)為“0.0.0.0”疏虫,consul將使用第一個(gè)有效的私有IPv4地址永罚。如果指定“[::]”,consul將使用第一個(gè)有效的公共IPv6地址卧秘。使用TCP和UDP通信呢袱。注意防火墻,避免無法通信翅敌。
3.4 結(jié)果
在開啟了"ui": true
server主機(jī)上羞福,如http://192.168.1.100:8500/ui查看注冊(cè)中心的服務(wù)。
demo ui如下:
4. 總結(jié)
本文介紹了consul的一些內(nèi)幕及consul配置相關(guān)蚯涮,并對(duì)項(xiàng)目中的一些實(shí)際配置進(jìn)行展示治专。希望能夠幫助大家對(duì)consul相關(guān)的知識(shí)有所了解,并對(duì)于入門配置consul和實(shí)際應(yīng)用有所知道恋昼。個(gè)人認(rèn)為看靠,consul原理還是簡(jiǎn)單易懂的,集群的配置也不復(fù)雜液肌,安利大家使用挟炬。后面會(huì)再寫一篇介紹Spring cloud中集成和使用consul組件作為注冊(cè)與發(fā)現(xiàn)中心。