內(nèi)衣網(wǎng)站建設(shè)詳細方案seo官網(wǎng)優(yōu)化詳細方法
1. 單機多節(jié)點
1.1 搭建RabbitMQ?
①安裝RabbitMQ
略?
②確認RabbitMQ運?沒問題
#查看RabbitMQ狀態(tài)
?rabbitmqctl status
?
?
節(jié)點名稱:
?
端口號:
- 25672:Erlang分布式節(jié)點通信的默認端?, Erlang是RabbitMQ的底層通信協(xié)議.
- 15672:?Web管理界?的默認端?, 通過這個端?可以訪問RabbitMQ的Web管理控制臺, ?于查看和管理消息隊列
- 5672:?AMQP 協(xié)議的默認端?, ?于客?端與 RabbitMQ服務(wù)器之間的通信.
③再啟動兩個節(jié)點
?
啟動命令:
RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}]" RABBITMQ_NODENAME=rabbit2 rabbitmq-server -detached
RABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15674}]" RABBITMQ_NODENAME=rabbit3 rabbitmq-server -detached?
④驗證RabbitMQ啟動成功
在云服務(wù)器開通 15673, 15674端?號:
分別測試:
119.91.154.99:15673/
119.91.154.99:15674/
?
1.2 搭建集群
①停?服務(wù)并重置
rabbitmqctl -n rabbit2 stop_app
rabbitmqctl -n rabbit2 reset
rabbitmqctl -n rabbit3?stop_app
rabbitmqctl -n rabbit3?reset
運行結(jié)果:
?
②把rabbit2, rabbit3添加到集群
rabbit@localhost是主節(jié)點的node Name?
rabbitmqctl -n rabbit2 join_cluster rabbit@localhost
rabbitmqctl -n rabbit3?join_cluster rabbit@localhost
③重啟rabbit2,rabbit3
rabbitmqctl -n rabbit2 start_app
rabbitmqctl -n rabbit3?start_app?
?
④查看集群狀態(tài)
?rabbitmqctl cluster_status -n rabbit
?
通過主節(jié)點(rabbit)管理界?, 可以看到集群其他節(jié)點:
2. 宕機演示
2.1 添加隊列
添加bit虛擬機,其它節(jié)點也有了這個虛擬機
在bit虛擬機中添加隊列:
2.2 添加之后,可以看到三個節(jié)點都有隊列了
?
2.3 往testQueue隊列中發(fā)送?條數(shù)據(jù)(從任?節(jié)點都可以)
?
發(fā)送之后, 觀察3個節(jié)點的隊列中均有消息:
2.4 關(guān)閉主節(jié)點
?
關(guān)閉后可以看到rabbit2和rabbit3沒有該隊列的數(shù)據(jù)了
?
也就是說, 這個數(shù)據(jù)只在主節(jié)點存在, 從節(jié)點沒有?
如何解決這個問題呢, 就需要引?"仲裁隊列"
3. 仲裁隊列(Quorum Queues)
RabbitMQ 的仲裁隊列是?種基于 Raft ?致性算法實現(xiàn)的持久化、復(fù)制的 FIFO 隊列. 仲裁隊列提供隊列復(fù)制的能?, 保障數(shù)據(jù)的?可?和安全性.
使?仲裁隊列可以在 RabbitMQ 節(jié)點間進?隊列數(shù)據(jù)的復(fù)制, 從?達到在?個節(jié)點宕機時, 隊列仍然可以提供服務(wù)的效果?
3.1 Raft協(xié)議介紹
Raft 是?種?于管理和維護分布式系統(tǒng)?致性的協(xié)議, 它是?種共識算法, 旨在實現(xiàn)?可?性和數(shù)據(jù)的 持久性. Raft 通過在節(jié)點間復(fù)制數(shù)據(jù)來保證分布式系統(tǒng)中的?致性,即使在節(jié)點故障的情況下也能保證數(shù)據(jù)不會丟失.
在分布式系統(tǒng)中, 為了消除單點提?系統(tǒng)可?性, 通常會使?副本來進?容錯, 但這會帶來另?個問題, 即如何保證多個副本之間的?致性?
共識算法就是做這個事情的, 它允許多個分布式節(jié)點就某個值或?系列值達成?致性協(xié)議. 即使在?些節(jié)點發(fā)?故障, ?絡(luò)分區(qū)或其他問題的情況下, 共識算法也能保證系統(tǒng)的?致性和數(shù)據(jù)的可靠性.
常?的共識算法有: Paxos, Raft, Zab等,此處用Raft算法
3.2 Raft 基本概念
Raft 使? Quorum 機制來實現(xiàn)共識和容錯, 我們將對 Raft 集群的操作必須得到?多數(shù)(> N/2)節(jié)點的同意才能提交.?
Raft 集群必須存在?個主節(jié)點(Leader), 客?端向集群發(fā)起的所有操作都必須經(jīng)由主節(jié)點處理. 所以 Raft 核?算法中的第?部分就是選主(Leader election). 沒有主節(jié)點集群就?法?作, 先選出?個主節(jié)點, 再考慮其它事情
主節(jié)點會負責(zé)接收客?端發(fā)過來的操作請求, 將操作包裝為?志同步給其它節(jié)點, 在保證?部分節(jié)點都 同步了本次操作后, 就可以安全地給客?端回應(yīng)響應(yīng)了. 這?部分?作在 Raft 核?算法中叫?志復(fù)制 (Log replication).
因為主節(jié)點的責(zé)任?常?, 所以只有符合條件的節(jié)點才可以當選主節(jié)點. 為了保證集群對外展現(xiàn)的?致 , 主節(jié)點在處理操作?志時, 也?定要謹慎, 這部分在Raft核?算法中叫安全性(Safety).
Raft算法將?致性問題分解為三個?問題: Leader選舉, ?志復(fù)制和安全性.
選主(Leader election)
?選主(Leader election)就是在集群中抉擇出?個主節(jié)點來負責(zé)?些特定的?作.
在執(zhí)?了選主過程后, 集群中每個節(jié)點都會識別出?個特定的, 唯?的節(jié)點作為 leader
角色
- Leader(領(lǐng)導(dǎo)者): 負責(zé)處理所有客?請求,并將這些請求作為?志項復(fù)制到所有 Follower. Leader 定期向所有 Follower 發(fā)送?跳消息, 以維持其領(lǐng)導(dǎo)者地位, 防? Follower 進?選舉過程.?
- Follower(跟隨者): 接收來? Leader 的?志條?, 并在本地應(yīng)?這些條?. 跟隨者不直接處理客?請求.?
- Candidate(候選者): 當跟隨者在?段時間內(nèi)沒有收到來? Leader 的?跳消息時,它會變得不確定 Leader 是否仍然可?. 在這種情況下, 跟隨者會轉(zhuǎn)變??成為 Candidate, 并開始嘗試通過投票過程成為新的 Leader.
在正常情況下, 集群中只有?個 Leader, 剩下的節(jié)點都是 follower.
所有節(jié)點在啟動時, 都是follow狀態(tài), 在?段時間內(nèi)如果沒有收到來?leader的?跳, 從 follower切換到candidate, 發(fā)起選舉. 如果收到多數(shù)派(majority)的投票(含??的?票) 則切換到 leader狀態(tài). Leader?般會?直?作直到它發(fā)?異常為?.
任期
Raft 將時間劃分成任意?度的任期(term). 每?段任期從?次選舉開始, 在這個時候會有?個或者多個 candidate 嘗試去成為 leader. 在成功完成?次leader election之后,?個leader就會?直節(jié)管理集群直到任期結(jié)束. 在某些情況下, ?次選舉?法選出 leader, 這個時候這個任期會以沒有 leader ?結(jié)束. 同時?個新的任期(包含?次新的選舉) 會很快重新開始
Term 更像是?個邏輯時鐘(logic clock)的作?, 有了它,就可以發(fā)現(xiàn)哪些節(jié)點的狀態(tài)已經(jīng)過期. 每?個節(jié)點都保存?個 current term, 在通信時帶上這個 term的值.
每?個節(jié)點都存儲著?個當前任期號(current term number). 該任期號會隨著時間單調(diào)遞增. 節(jié)點之間通信的時候會交換當前任期號, 如果?個節(jié)點的當前任期號?其他節(jié)點?, 那么它就將??的任期號更新為較?的那個值. 如果?個 candidate 或者 leader 發(fā)現(xiàn)??的任期號過期了, 它就會?刻回到 follower 狀態(tài). 如果?個節(jié)點接收了?個帶著過期的任期號的請求, 那么它會拒絕這次請求.
Raft 算法中服務(wù)器節(jié)點之間采? RPC 進?通信, 主要有兩類 RPC 請求:
- RequestVote RPCs: 請求投票, 由 candidate 在選舉過程中發(fā)出
- AppendEntries RPCs: 追加條?, 由 leader 發(fā)出, ?來做?志復(fù)制和提供?跳機制
選舉過程?
Raft 動畫演?官方在線地址: https://raft.github.io/??
Raft 采??種?跳機制來觸發(fā) leader 選舉, 當服務(wù)器啟動的時候, 都是follow狀態(tài). 如果follower在 election timeout內(nèi)沒有收到來?leader的?跳(可能沒有選出leader, 也可能leader掛了, 或者leader與 follower之間?絡(luò)故障), 則會主動發(fā)起選舉
所有節(jié)點均為follow狀態(tài):
步驟如下:
- 率先超時的節(jié)點, ?增當前任期號然后切換為 candidate 狀態(tài), 并投???票
- 以并?的?式發(fā)送?個 RequestVote RPCs 給集群中的其他服務(wù)器節(jié)點(企圖得到它們的投票)
- 等待其他節(jié)點的回復(fù)
S1節(jié)點率先超時,把任期號改為2,切換為candidate 狀態(tài), 并投???票:
在這個過程中, 可能出現(xiàn)三種結(jié)果
- 贏得選舉, 成為Leader(包括??的?票)?
- 其他節(jié)點贏得了選舉, 它??切換到follower?
- ?段時間內(nèi)沒有收到majority投票, 保持candidate狀態(tài), 重新發(fā)出選舉
投票要求:
- 每?個服務(wù)器節(jié)點會按照 先來先服務(wù)原則(first-come-first-served)只投給?個 candidate.
- 候選人知道的信息不能比自己少
接下來對這三種情況進?說明:
①贏得了選舉之后, 新的leader會?刻給所有節(jié)點發(fā)消息, ??告之, 避免其余節(jié)點觸發(fā)新的選舉.
②?如有三個節(jié)點A B C, A B同時發(fā)起選舉, ?A的選舉消息先到達C, C給A投了?票, 當B的消息到達C時, 已經(jīng)不能滿?上?提到的第?個約束, 即C不會給B投票, 這時候A就勝出了. A勝出之后, 會給 B,C發(fā)?跳消息, 節(jié)點B發(fā)現(xiàn)節(jié)點A的term不低于??的term, 知道有已經(jīng)有Leader了, 于是把??轉(zhuǎn)換成follower.
S5收到S1的心跳消息,發(fā)現(xiàn)S1的term不低于自己,知道有l(wèi)eader了,把自己切換為follower:
③沒有任何節(jié)點獲得majority投票. ?如所有的 follower 同時變成 candidate, 然后它們都將票投給??, 那這樣就沒有 candidate 能得到超過半數(shù)的投票了. 當這種情況發(fā)?的時候, 每個 candidate 都會進??次超時響應(yīng), 然后通過?增任期號來開啟?輪新的選舉, 并啟動另?輪的 RequestVote RPCs. 如果沒有額外的措施, 這種?結(jié)果的投票可能會?限重復(fù)下去
注意:
為了解決上述問題,Raft 采?隨機選舉超時時間來確保很少產(chǎn)??結(jié)果的投票,并且就算發(fā)?了也能很快地解決。
為了防?選票?開始就被?分,選舉超時時間是從?個固定的區(qū)間(?如,150-300ms)中隨機選擇。這樣可以把服務(wù)器分散開來以確保在?多數(shù)情況下會只有?個服務(wù)器率先結(jié)束超時,那么這個時候,它就可以贏得選舉并在其他服務(wù)器結(jié)束超時之前發(fā)送?跳。?
3.3 Raft 協(xié)議下的消息復(fù)制?
每個仲裁隊列都有多個副本, 它包含?個主和多個從副本. replication factor 為 5的仲裁隊列將會有 1個 主副本和 4 個從副本. 每個副本都在不同的 RabbitMQ 節(jié)點上
客?端(?產(chǎn)者和消費者)只會與主副本進?交互, 主副本再將這些命令復(fù)制到從副本. 當主副本所在的節(jié)點下線, 其中?個從副本會被選舉成為主副本, 繼續(xù)提供服務(wù).
消息復(fù)制和主副本選舉的操作, 需要超過半數(shù)的副本同意. 當?產(chǎn)者發(fā)送?條消息, 需要超過半數(shù)的隊列副本都將消息寫?磁盤以后才會向?產(chǎn)者進?確認, 這意味著少部分?較慢的副本不會影響整個隊列的性能.
3.4 仲裁隊列的使?
①創(chuàng)建仲裁隊列
1)使?Spring框架代碼創(chuàng)建
2)使?管理平臺創(chuàng)建
創(chuàng)建時選擇Type為Quorum, 指定主副本?
?
②創(chuàng)建后觀察管理平臺
?
+2表示有兩個副本?
點進去看隊列詳情:
對比普通隊列:
③接收/發(fā)送消息
?
3.5 宕機演示?
①?給仲裁隊列 quorum_queue 發(fā)送消息
?
②停掉隊列主副本所在的節(jié)點
?
觀察其他節(jié)點, 可以看到quorum_queue 隊列的內(nèi)容依然存在:
并且, 因為主副本所在節(jié)點宕機了, quorum_queue 主副本從rabbit@localhost 轉(zhuǎn)移到了 rabbit3@localhost+1
隊列詳細信息: 只剩下兩個成員了:
?
4.?HAProxy 負載均衡
?對?量業(yè)務(wù)訪問、?并發(fā)請求,可以使??性能的服務(wù)器來提升RabbitMQ服務(wù)的負載能?.
當單機容量達到極限時, 可以采取集群的策略來對負載能?做進?步的提升, 但這?還存在?些問題.
試想如果?個集群中有3個節(jié)點, 我們在寫代碼時, 訪問哪個節(jié)點呢?
答案是訪問任何?個節(jié)點都可以.
這時候就存在兩個問題:
- 如果我們訪問的是node1, 但是node1掛了, 咱們的程序也會出現(xiàn)問題, 所以最好是有?個統(tǒng)?的??, ?個節(jié)點故障時, 流量可以及時轉(zhuǎn)移到其他節(jié)點.
- 如果所有的客?端都與node1建議連接, 那么node1的?絡(luò)負載必然會??增加, ?其他節(jié)點?由于沒有那么多的負載?造成硬件資源的浪費.
引?負載均衡之后, 各個客?端的連接可以通過負載均衡分攤到集群的各個節(jié)點之中, 從?避免前?的問題.
這?講?下使?HAProxy來實現(xiàn)負載均衡.
4.1 安裝
安裝HAProxy
?#更新軟件包
sudo apt-get update
#查找haproxy
sudo apt list|grep haproxy
#安裝haproxy
sudo apt-get install haproxy
驗證安裝
#查看服務(wù)狀態(tài)
sudo systemctl status haproxy
#查看版本
haproxy -v
#如果要設(shè)置HAProxy服務(wù)開機?啟,可以使?:
sudo systemctl enable haproxy
修改haproxy.cfg
vim /etc/haproxy/haproxy.cfg
加入以下內(nèi)容:
# haproxy web 管理界面
listen stats
? ? bind *:8100 ? ? ??
? ? mode http
? ? stats enable
? ? stats realm Haproxy\ Statistics ? ?
? ? stats uri /
? ? stats auth admin:admin
# 配置負載均衡
listen rabbitmq
? ? bind *:5670
? ? mode tcp
? ? balance roundrobin
? ? server ?rabbitmq1 127.0.0.1:5672 ?check inter 5000 rise 2 fall 3
? ? server ?rabbitmq2 127.0.0.1:5673 ?check inter 5000 rise 2 fall 3
? ? server ?rabbitmq3 127.0.0.1:5674 ?check inter 5000 rise 2 fall 3?
?解釋:
- server rabbitmq1 : 定義RabbitMQ服務(wù)的內(nèi)部標識, 這?的rabbitmq1 是指haproxy內(nèi)部使?的, 不是指RabbitMQ的節(jié)點名稱
- 127.0.0.1:5672 : RabbitMQ真實的IP和端?
- check inter 5000 : 定義每隔多少毫秒檢查RabbitMQ服務(wù)是否可?
- rise 2 : 定義RabbitMQ服務(wù)在發(fā)?故障之后,需要多少次健康檢查才能被再次確認可?.
- fall 3 : 定義需要經(jīng)歷多少次失敗的健康檢查之后,HAProxy才會停?使?此RabbitMQ服務(wù)
重啟HAPROXY
sudo systemctl restart haproxy?
查看HAProxy
通過119.91.154.99:8100訪問
?
?
4.2 使用
①修改配置文件
spring:rabbitmq:addresses: amqp://admin:admin@119.91.154.99:5670/ops
②聲明隊列 test_cluster
?
③發(fā)送消息
?
④測試
?
⑤宕機演示
停?其中?個節(jié)點, 繼續(xù)測試步驟2的代碼:
再次發(fā)送:
顯?隊列中有兩條數(shù)據(jù)
?
⑥集群恢復(fù)
觀察消息也同步到當前節(jié)點了:?
?