鏡像隊列是比較常用的實現RabbitMQ高可用方式,官方文檔還提到了另外一種高可用方式High availability with Pacemaker and DRBD,但是它自己都說了"This part documents a technique for achieving active-passive high availability with RabbitMQ. Mirrored queues can be easier to use and do not impose a delay at failover."
1 mirror隊列
默認啓動集羣后,每一條消息隊列只存在於一個單點服務器中,如果這臺服務器狗帶,那數據就丟失了
可以用鏡像隊列來解決這個問題,即一個消息隊列存在多個服務器裏,當然需要性能上的代價
關於鏡像隊列的官方文檔https://www.rabbitmq.com/ha.html
每個鏡像隊列,都包括一個master和若干個mirror,每次操作會首先在master隊列上進行,其次才輪到其他mirror。如果master掛了,最老的已完成同步的mirror會被提升爲master,也可以提升未同步的mirror,這取決於配置。如果配置不允許未同步的mirror成爲master,那master一掛就後繼無人,隊列就狗帶了
所謂同步,就是指一臺機器新啓動後,等到隊列內容與master節點完全相同,就稱爲同步完成
舉個例子,master節點的隊列中有消息1和消息2,這時候啓動一臺mirror,mirror的隊列是空的;插入消息3,master的隊列是消息1、2、3,mirror的隊列是消息3,並未同步成功;然後取出消息1和消息2,master和mirror的隊列只含有消息3,就是同步完成了
官方建議一個隊列的鏡像數最好是集羣的半數加一,例如三點集羣,鏡像隊列存在於兩個節點
2 配置mirror隊列
在配置一個隊列進入鏡像模式時,需要兩個參數,ha-mode和ha-params,一共有三種鏡像模式,參數如下
模式(ha-mode) | 參數(ha-params) | 說明 |
exactly | count | 指定備份個數,如果count爲1,表示只有一個master的情況 |
all | 無 | 所有集羣中的節點都存有一個隊列mirror |
nodes | 節點列表 | 指定的節點列表上都有一個隊列mirror |
配置一個隊列是通過policy完成批量配置的,一個policy可以匹配多個隊列(只要符合匹配規則),所以批量化地修改配置非常方便,policy由四個部分組成:
- name: 名稱,可以使用任何名稱,但是推薦使用沒有空格的ASCII字符
- pattern: 正則表達式,用於匹配隊列的名字
- definition: 一組key/value,對應隊列和交互機的參數
- priority: 優先級,當多個policy匹配一個隊列時,最高優先級的policy生效
配置policy有三種方法
2.1 網頁UI配置
現在來實戰一下,用web頁面進行操作
首先配置vhost,表示一個獨立的空間,賬號策略隊列都在這個vhost裏面,不受其他影響。這是還沒有配置vhost的界面,所有的操作都在根目錄下 ,點擊Add a new virtual host,添加一個vhost
再添加一個policy,作用於所有隊列
最後新建一個隊列,可以看到我們的策略已經生效了,點一下隊列名字看一下
兩個鏡像,完美
2.2 API配置
在使用API的時候要進行身份驗證,如果是用curl,要用下面的命令
curl -i -u user:password url
用postman,在Authorization選項卡里,選擇Basic Auth,填寫用戶名和密碼
配置policy的API是/api/policies/vhost/name,最後一個name是你要添加的policy名,vhost替換爲要添加policy的vhost名字,支持get、put、delete
現在虛擬主機/下面有一個名爲hello的隊列,爲他新建一條policy
發送json到api/policies/%2f/apply-all-mirror,動作是put
{
"pattern":"hello",
"definition":{
"ha-mode": "exactly",
"ha-params": 2
},
"priority":1,
"apply-to":"queues"
}
看一下頁面上,多了一個新增的policy
hello隊列已經進入鏡像模式
2.3 命令行配置
命令行配置很簡單,一條命令搞定,下面是用命令行配置了一條和2.2完全相同的policy
./rabbitmqctl set_policy -p / --priority 1 --apply-to queues apply-all-mirror hello '{"ha-mode": "exactly","ha-params":2}'