EMQ X 的主題重寫功能支持根據用戶配置的規則在 MQTT 客戶端訂閱主題、發佈消息、取消訂閱的時候將 A 主題重寫爲 B 主題。
EMQ X 的 保留消息 和 延遲發佈 可以與主題重寫配合使用,例如,當用戶想使用延遲發佈功能,但不方便修改客戶端發佈的主題時,可以使用主題重寫將相關主題重寫爲延遲發佈的主題格式。
開啓主題重寫功能
主題重寫功能默認關閉,開啓此功能需要修改 etc/emqx.conf
文件中的 module.rewrite
配置項。默認 off
表示關閉,如需開啓請修改爲 on
。
module.rewrite = off
配置主題重寫規則
EMQ X 的主題重寫規則需要用戶自行配置,用戶可以自行添加多條主題重寫規則,規則的數量沒有限制,但由於任何攜帶主題的 MQTT 報文都需要匹配一遍重寫規則,因此此功能在高吞吐場景下帶來的性能損耗與規則數量是成正比的,用戶需要謹慎地使用此功能。
每條主題重寫規則的格式如下:
module.rewrite.rule. = 主題過濾器 正則表達式 目標表達式
每條重寫規則都由以空格分隔的主題過濾器、正則表達式、目標表達式三部分組成。在主題重寫功能開啓的前提下,EMQ X 在收到諸如 PUBLISH 報文等帶有主題的 MQTT 報文時,將使用報文中的主題去依次匹配配置文件中規則的主題過濾器部分,一旦成功匹配,則使用正則表達式提取主題中的信息,然後替換至目標表達式以構成新的主題。
目標表達式中可以使用 $N
這種格式的變量匹配正則表達中提取出來的元素,$N
的值爲正則表達式中提取出來的第 N 個元素,比如 $1
即爲正則表達式提取的第一個元素。
需要注意的是,EMQ X 使用倒序讀取配置文件中的重寫規則,當一條主題可以同時匹配多條主題重寫規則的主題過濾器時,EMQ X 僅會使用它匹配到的第一條規則進行重寫,如果該條規則中的正則表達式與 MQTT 報文主題不匹配,則重寫失敗,不會再嘗試使用其他的規則進行重寫。因此用戶在使用時需要謹慎的設計 MQTT 報文主題以及主題重寫規則。
示例
假設 etc/emqx.conf
文件中已經添加了以下主題重寫規則:
module.rewrite.rule.1 = y/+/z/# ^y/(.+)/z/(.+)$ y/z/KaTeX parse error: Can't use function '\=' in math mode at position 27: …rewrite.rule.2 \̲=̲ x/\# ^x/y/(.+) z/y/x/KaTeX parse error: Can't use function '\=' in math mode at position 27: …rewrite.rule.3 \̲=̲ x/y/+ ^x/y/(\\… z/y/$1
此時我們分別訂閱 y/a/z/b
、y/def
、x/1/2
、x/y/2
、x/y/z
五個主題:
-
y/def
不匹配任何一個主題過濾器,因此不執行主題重寫,直接訂閱y/def
主題。 -
y/a/z/b
匹配y/+/z/#
主題過濾器,EMQ X 執行module.rewrite.rule.1
規則,通過正則正則表達式匹配出元素[a、b]
,將匹配出來的第二個元素帶入y/z/$2
,實際訂閱了y/z/b
主題。 -
x/1/2
匹配x/#
主題過濾器,EMQ X 執行module.rewrite.rule.2
規則,通過正則表達式未匹配到元素,不執行主題重寫,實際訂閱x/1/2
主題。 -
x/y/2
同時匹配x/#
和x/y/+
兩個主題過濾器,EMQ X 通過倒序讀取配置,所以優先匹配module.rewrite.rule.3
,通過正則替換,實際訂閱了z/y/2
主題。 -
x/y/z
同時匹配x/#
和x/y/+
兩個主題過濾器,EMQ X 通過倒序讀取配置,所以優先匹配module.rewrite.rule.3
,通過正則表達式未匹配到元素,不執行主題重寫,實際訂閱x/y/z
主題。需要注意的是,即使module.rewrite.rule.3
的正則表達式匹配失敗,也不會再次去匹配module.rewrite.rule.2
的規則。