В предыдущая часть Мы улучшили нашу систему журналирования.
Вместо использования разветвленного обменника мы использовали прямой обменник, что позволило нам выборочно принимать сообщения.
Несмотря на улучшения, наша система по-прежнему имеет ограничения, например, мы не можем принимать сообщения по нескольким критериям.
Например, в нашей системе мы можем захотеть перенаправлять сообщения не только в зависимости от уровня серьезности сообщения, но и в зависимости от источника сообщения.
Например, как в инструменте Unix системный журнал , который перенаправляет сообщения не только в зависимости от уровня серьезности (info/warn/crit.), но и в зависимости от источника (auth/cron/kern.).
Это может дать нам дополнительную гибкость, например, мы можем получать только критические сообщения от «cron», но также и все сообщения от «kern».
Для реализации такой системы нам предстоит познакомиться с более сложным типом обменника — тема .
Оглавление всех частей: Часть 1 Часть 2 Часть 3 Часть 4 Часть 5
Обмен тем
Сообщения, отправляемые в обменник типа «Тема», должны иметь ключ маршрутизации, который представляет собой набор слов, разделенных точками.Слова могут быть какими угодно, но обычно они связаны с какой-то особенностью сообщения.
Вот примеры некоторых допустимых ключей маршрутизации: "stock.usd.nyse" , "nyse.vmw" , "быстрый.
оранжевый.
кролик" .
Размер ключа ограничен 255 байтами.
Ключ привязки должен быть указан аналогичным образом.
Маршрутизация сообщений в тематическом обменнике аналогична маршрутизации прямого обменника — сообщение отправляется в очередь с ключом привязки, совпадающим с ключом маршрутизации.
Однако есть два различия:
- *(звездочку) в ключе привязки можно заменить только одним словом
- #(хэш) в ключе привязки может быть заменен нулем или более словами.
(изображение взято с Официальный сайт RabbitMQ ) В этом примере мы будем отправлять сообщения, представляющие животных.
Ключи маршрутизации сообщений состоят из трех слов (и двух точек).
Первое слово обозначает скорость, второе — цвет, а третье — внешний вид. В нашем примере с обменником связаны две очереди: Q1 с ключом привязки "*.
апельсин.
*" и Q2 с двумя ключами привязки "*.
*.
кролик" И "ленивый.
#" .
Эти соединения будут означать следующую маршрутизацию:
- Q1 интересуют все оранжевые животные.
- Q2 интересует всех кроликов и ленивых животных.
оранжевый.
кролик" будут доставлены в обе очереди.
Ключевое сообщение "ленивый.
оранжевый.
слон" также будет доставлен обоим.
Однако сообщение с ключом "быстрый.
оранжевый.
лис" ударит только первым, но с ключом "ленивый.
коричневый.
лис" только во втором.
"ленивый.
розовый.
кролик" будет доставлен во вторую очередь один раз, несмотря на то, что ключ маршрутизации соответствует обоим ключам привязки.
"быстрый.
коричневый.
лис" не попадет ни в одну очередь, так как ключ маршрутизации не соответствует ни одному из ключей привязки.
Если вы попытаетесь отправить сообщение с меньшим или большим количеством слов в ключе маршрутизации (например, "апельсин" или "быстрый.
оранжевый.
самец.
кролик" ), чем в ключе привязки сообщение будет отброшено.
Обменник типа топик может вести себя как обменник типа разветвление, если вы укажете # .
Или как напрямую, если в ключе привязки ничего не указать * ни один # , а просто укажите какое-нибудь слово.
Собираем код вместе
Мы будем использовать обменник тем для нашей системы журналирования.Начнем с предположения, что наши ключи маршрутизации сообщений будут выглядеть так "источник.
строгость" .
Код будет практически такой же, как и в предыдущей части, вот он send.php :
Код рабочий-1.phptry { $producer = \MonsterMQ\Client\Producer(); $producer->connect('127.0.0.1', 5672); $producer->logIn('guest', 'guest'); $producer->newTopicExchange('topic-logs'); $routingKey = isset($argv[1]) && !empty($argv[1]) ? $argv[1] : 'anonymous.info'; $message = implode(' ', array_slice($argv, 2)); $message = empty($message) ? "Hello World!" : $message; $producer->publish($message, $routingKey, 'topic-logs'); echo "\n Sent {$message} \n"; } catch(\Exception $e) { var_dump($e); }
try {
$consumer = \MonsterMQ\Client\Consumer();
$consumer->connect('127.0.0.1', 5672);
$consumer->logIn('guest', 'guest');
$producer->queue('queue-1')->setExclusive()->declare();
$consumer->newTopicExchange('topic-logs');
$bindingKeys = array_slice($argv, 1);
if (empty($bindingKeys)) {
file_put_contents(' php://stderr ', "Usage: $argv[0] [binding_key]\n");
exit(1);
}
foreach ($bindingKeys as $key) {
$producer->queue('queue-1')->bind('topic-logs', $key);
}
$consumer->consume('queue-1');
echo " \n Waiting for logs. To exit press CTRL+C\n";
$consumer->wait(function ($message, $channelNumber) use ($consumer){
echo "\n $message \n";
});
} catch(\Exception $e) {
var_dump($e);
}
Код рабочий-2.php
try {
$consumer = \MonsterMQ\Client\Consumer();
$consumer->connect('127.0.0.1', 5672);
$consumer->logIn('guest', 'guest');
$producer->queue('queue-2')->setExclusive()->declare();
$consumer->newTopicExchange('topic-logs');
$bindingKeys = array_slice($argv, 1);
if (empty($bindingKeys)) {
file_put_contents(' php://stderr ', "Usage: $argv[0] [binding_key]\n");
exit(1);
}
foreach ($bindingKeys as $key) {
$producer->queue('queue-2')->bind('topic-logs', $key);
}
$consumer->consume('queue-2');
echo " \n Waiting for logs. To exit press CTRL+C\n";
$consumer->wait(function ($message, $channelNumber) use ($consumer){
echo "\n $message \n";
});
} catch(\Exception $e) {
var_dump($e);
}
Чтобы получать только критические сообщения от первого работника, позвоните
php worker-1.php "*.
critical"
Чтобы привязать очередь, используемую вторым воркером, к обменнику двумя ключами привязки, вызовите:
php worker-2.php "kern.*" "*.
critical"
Чтобы отправить сообщение, сделайте что-то вроде:
php send.php "kern.critical" "A critical kernel error"
Поэкспериментируйте с этими программами.
Теги: #php
-
Либби, Уиллард Фрэнк
19 Oct, 24 -
Блейд-Серверы Для Замены Штатных.
19 Oct, 24 -
Symfony 4: Структурирование Приложений
19 Oct, 24 -
Каким Вы Видите Ит-Образование?
19 Oct, 24 -
Таймс Нью Роман - Запретить
19 Oct, 24 -
Представляем Youtrack Lite
19 Oct, 24 -
Для Фанатов Супер Марио
19 Oct, 24