direct、fanout、topic、headers 四种 exchange 到底按什么规则把消息分给队列?topic 的 # 能不能匹配零个单词,headers 多出一个头会怎样,绑定很多时谁会变慢?这篇每种都建好队列、发出一批 key,把每个队列真实收到的东西列成表。
d.a 收到 1 条: ["key='red'"] d.b 收到 1 条: ["key='blue'"] d.c 收到 2 条: ["key='red'", "key='blue'"] 发布了 5 条(red、blue、green、Red、"red "):green、Red(大小写不同)和 "red "(末尾空格)没有任何绑定,直接丢弃;d.c 绑了两个 key,red 和 blue 各收一条
routing key 与绑定 key 逐字节相等才路由,大小写、空格都算。一个队列可以用多个 key 绑同一个 exchange;没有匹配的消息直接丢弃。
f.a 收到 3 条: ["key='anything'", "key=''", "key='k1'"] f.b 收到 3 条: ["key='anything'", "key=''", "key='k1'"] f.c 收到 3 条: ["key='anything'", "key=''", "key='k1'"] 3 条消息 × 3 个队列 = 每个队列都收到 3 条,与发布时和绑定时的 routing key 都无关
不看 routing key,所有绑定的队列各收一份。绑定时给的 key 也被忽略。
routing key t.orange t.rabbit t.lazy t.all quick.orange.rabbit ✓ ✓ · ✓ lazy.orange.elephant ✓ · ✓ ✓ quick.orange.fox ✓ · · ✓ lazy.brown.fox · · ✓ ✓ lazy.pink.rabbit · ✓ ✓ ✓ quick.brown.fox · · · ✓ orange · · · ✓ quick.orange.male.rabbit · · · ✓ lazy.orange.male.rabbit · · ✓ ✓ lazy · · ✓ ✓ 各队列收到的条数: t.orange=3, t.rabbit=2, t.lazy=5, t.all=10
key 是点分的单词。* 匹配恰好一个单词,# 匹配零个或多个单词(所以 lazy.# 也能匹配 lazy 本身)。表里每个 key 对每个绑定的匹配结果都是真实收到的。
消息头 h.all h.any pdf+report ✓ ✓ pdf+log · ✓ txt+report · ✓ txt only · · pdf+report+extra ✓ ✓ 无头 · ·
按消息头匹配,忽略 routing key。x-match=all 要求绑定里列的每个头都匹配,any 只要一个;消息多出来的头不影响匹配。
u.q 收到 1 条: ['a.b 这一条'] u.q2 收到 1 条: ['a.b 这一条'] u.q 有 3 个绑定(a.*、#、a.b)都匹配 a.b,队列里仍只有 1 份
一条消息命中同一个队列的多个绑定,队列里只有一份;命中几个队列就复制几份。
绑定数 B 10 100 1000 direct 272 ms 272 ms 276 ms topic 277 ms 278 ms 295 ms headers 266 ms 426 ms 3387 ms
direct 和 topic 的匹配基本不随绑定数增长;headers 要逐个比较绑定,1000 个绑定时 10000 条消息用了 3387 ms,而 direct 只要 276 ms。