Header Exchange¶
Header Exchange - самый сложный и гибкий способ маршрутизации сообщений в RabbitMQ. Данный тип exchange отправляет сообщения
в очереди в соответствии с совпадением аргументов привязки этих очередей к exchange с заголовками сообщений.
При этом, если очередь слушает несколько потребителей, сообщения все также будут распределяться между ними.
Пример¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
Объявление потребителей¶
Для начала мы объявили наш Fanout exchange и несколько очередей, которые будут его слушать:
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Аргумент x-match говорит о том, должны сопадать аргументы с заголовками сообщений полностью или частично.
Затем мы подписали несколько потребителей с помощью объявленных очередей на созданный нами exchange
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | |
Note
Обратите внимание, что handler1 и handler2 подписаны на один exchange с помощью одной и той же очереди:
в рамках одного сервиса это не имеет смысла, так как сообщения будут приходить в эти обработчики поочередно.
Здесь мы эмулируем работу несколько потребителей и балансировку нагрузки между ними.
Распределение сообщений¶
Теперь распределение сообщений между этими потребителями будет выглядеть следующим образом:
await broker.publish(exchange=exch, headers={ "key": 1 }) # handlers: 1
Сообщение 1 будет отправлено в handler1, т.к. он слушает очередь, заголовок key которой, совпал с заголовком key сообщения
await broker.publish(exchange=exch, headers={ "key": 1 }) # handlers: 2
Сообщение 2 будет отправлено в handler2, т.к. он слушает exchange с помощью той же очереди, но handler1 занят
await broker.publish(exchange=exch, headers={ "key": 1 }) # handlers: 1
Сообщение 3 снова будет отправлено в handler1, т.к. он освободился на данный момент
await broker.publish(exchange=exch, headers={ "key": 2 }) # handlers: 3
Сообщение 4 будет отправлено в handler3, т.к. он слушает очередь, заголовок key которой, совпал с заголовком key сообщения
await broker.publish(exchange=exch, headers={ "key2": 2 }) # handlers: 3
Сообщение 5 будет отправлено в handler3, т.к. он слушает очередь, заголовок key2 которой, совпал с заголовком key2 сообщения
await broker.publish(exchange=exch, headers={ "key": 2, # handlers: 3, 4
"key2": 2 })
Сообщение 6 будет отправлено в handler3 и handler4, т.к. заголовки сообщений полностью совпали с ключами очередей
Note
При отправке сообщений в Header exchange нет смысл указывать аргументы queue или routing_key, т.к. они будут проигнорированы
Warning
Для невероятно сложных маршрутов вы можете использовать возможность подписывать exchange на другой exchange с указанием ключа маршрутизации. В таком случае действуют все те же правила, что и для очередей, подписанных на exchange. Отличие только в том, что подписанный exchange может дальше распределять сообщения в соответствии со своими правилами.
Так, например, вы можете совместить Topic и Header типы.