前言
此篇單純講解什麼是 Federation Plugin 與他的相關設定知識,如果想知道實際上怎麼用請參考【RabbitMQ】不架設 cluster 也能達到 load balancing 效果,federation 實戰。
介紹 Federation
Federation 主要目的就是要在不建構 cluster 的情況下,在不同 broker 間傳送訊息,而 Federation 也擁有 cluster 辦不到的事情。
broker 基本上可以想成一個 RabbitMQ server 或者是 RabbitMQ cluster
以下講解 Federation 的特色:
1. 對其他 Node 或 Cluster 的依賴較低
- broker 間可以有不同的使用者跟 virtual hosts
- broker 間可已有不同的 RabbitMQ 版本
2. WAN 友善
- 透過 AMQP 在 broker 間傳輸,因此可以跨網域
- 可以接受斷斷續續的連線,因此網路若較差一樣能正常運作
3. 獨特性
Federation 可以讓 broker 同時使用 federated 和 local-only components。這個聽起來有點抽象,但其實就是如下圖這樣,在同時擁有 federation 功能的同時,左半邊依舊可以看到該 broker 擁有著屬於自己的 local queue,不受限於只能有 federated 或 local-only components 的關係。
4. 擴展性高
Federation 能夠根據設計的 topology 不同,可以降低 brokers 間所需要的 connections;也可以透過這個特性,不管 connection 數量,直接套個最簡單的 topology 完成設定。
Federation 的設定
而要啟用 Federation 除了安裝 plugin 之外,還需要定義些必要的 Parameters 跟 policies。而這些設定都存在 RabbitMQ database,跟 users, permissions, queues 都放在一起。
- Upstreams: 每個 upstream 都會定義如何連接到另一個 broker
- Upstream sets: 每個 upstream 都需要指定所歸屬的 set 來判定是不是屬於同一群 federation,基本上有個隱藏的 upstream sets 叫 all,基本上沒有特殊需求可以直接用 all 即可
- Policies: 每個 policy 都要設定用那個 upstream 或者是一整個 upstream set,並且會將這個 upstream set 關連到 exchanges 或 queues,甚至兩個都關連
這些主要的設定,有數種方式可以進行,將一一介紹。
Upstream
首先 upstream 是使用 json-object 來進行設定,以下是這個 json-object 可以設定的參數介紹
參數介紹
uri
這個是唯一一定要給的參數!
- 使用 AMQP URI 來當 federation link
- 可以是 string 也可以是 list of strings,如果給複數 URI 在連線時會隨機挑一個用。
prefetch-count
- 預設為 1000
- 用來決定 federation link throughput 數量,數量越多用的記憶體越大。
- 就是 message 送到 queue 還沒收走的數量上限
reconnect-delay
- 預設為 1 (單位為秒)
- 斷線後隔多久要重新嘗試連回 broker 的時間
ack-mode
- 預設為 on-confirm
- 主要有三種模式:on-confirm、on-publish、no-ack
- on-confirm 最慢、最安全,會等到收到的 broker 回應處理完才算結束
- on-publish 確保網路傳輸沒問題,但是 broker 如果處理發生錯誤,就不管了
- no-ack 最快、最不安全,基本上送出去就結束,不管對方有沒有收到
trust-user-id
- 建議為 true,主要是跟 validated user-id 整合的功能
- 若為 false 或不設定,會清除遇到的任何 validated user-id
exchange
federated exchange only
- 預設使用為 federated exchange 的名字
- 用來設定 upstream exchange 的名字
max-hops
federated exchange only
- 預設為 1
- message 路過 federation link 的最大數量
expires
federated exchange only
- 預設為 none,upstream queue 永遠不會 expire 而被刪掉
- 時間設定使用為 milliseconds (e.g. 1000 代表 1秒)
- 這個主要是當 federation link 斷開後,在 upstream 上的 queue 多久會被移除
message-ttl
federated exchange only
- 預設為 none,在 upstream queue 上的訊息,如果沒人收走也永遠不會 expire 而被清掉
- 時間設定使用為 milliseconds (e.g. 1000 代表 1秒)
- 這個主要是當 federation link 斷開後,在 upstream queue 上的 message 多久會被移除
queue
federated queue only
設定 upstream queue 的名字,預設為 federated queue 的名字
consumer-tag
federated queue only
- 非必要
- 要從 upstream node 進行 consume 時使用的 tag
如何設定 Upstream
1. 定義在 definitions.json 裡
通常 upstream 的設定會是動態的,所以此處就不給範例了。原因為通常使用 upstream 你需要確保各個 broker 都起來,不然就是他們的資訊永遠是固定的,不需要你額外去拿取。但現實是殘酷的,通常他們變動的機率都很高。
2. 透過 rabbitmqctl 定義
rabbitmqctl set_parameter federation-upstream my-upstream \'{"uri":"amqp://server-name","expires":3600000}'
3. 透過 HTTP API 定義
PUT 為設定;GET 為拿取;DELETE 為刪除
PUT /api/parameters/federation-upstream/%2f/my-upstream{"value":{"uri":"amqp://server-name","expires":3600000}}
4. 透過 Management Web UI 定義
由 rabbitmq_federation_management 提供
- admin > Federation Upstream
Policy 設定
- 定義在 definitions.json 裡
policy 反而推薦直接提前定義
"policies": [
{
"definition": {
"federation-upstream-set": "all"
},
"name": "connect_to_all_upstreams",
"pattern": "ex_overlay",
"priority": 0,
"vhost": "/",
"apply-to": "exchanges"
},
{
"definition": {
"expires": 1800000
},
"name": "QueueExpires",
"pattern": "^(q_scg_ccm_server.*|q_md.*)",
"priority": 5,
"vhost": "/",
"apply-to": "queues"
}
],
2. 透過 rabbitmqctl 定義
rabbitmqctl set_policy --apply-to exchanges federate-me "^amq\." '{"federation-upstream-set":"all"}'
3. 透過 HTTP API 定義
PUT 為設定;GET 為拿取;DELETE 為刪除
PUT /api/policies/%2f/federate-me{"pattern":"^amq\.", "definition":{"federation-upstream-set":"all"}, \"apply-to":"exchanges"}
4. 透過 Management Web UI 定義
由 rabbitmq_federation_management 提供
- admin > Policies