112
Готовим кролика 10 рецептов Календарев А.М.

Рецепты RabbitMQ

Embed Size (px)

Citation preview

Page 1: Рецепты RabbitMQ

Готовим кролика

10 рецептов

Календарев А.М.

Page 2: Рецепты RabbitMQ

Пару слов об pipeline архитектуреhttps://habrahabr.ru/company/oleg-bunin/blog/310418/

Page 3: Рецепты RabbitMQ

Pipe-line архитектура

Page 4: Рецепты RabbitMQ

Pipe-line архитектура

ApplicationApplication Application

Page 5: Рецепты RabbitMQ

Пример: аналог Yandex.market

Page 6: Рецепты RabbitMQ

Пример: аналог Yandex.market

ЗагрузкаYML

Сведениев pricelist

ПарсингYML

Загрузкаimg

Задачи за кадром

Page 7: Рецепты RabbitMQ

Пример: аналог Yandex.market

ЗагрузкаYML

Сведениев pricelist

ПарсингYML

Загрузкаimg

Задачи за кадром

Page 8: Рецепты RabbitMQ

Паттерны сообщений

Page 9: Рецепты RabbitMQ

Cообщения

● Позволяют асинхронно взаимодействоавть между элементами архитектуры

● Сохраняют слабую связанность между элементами архитектуры

● Позволяют взаимодействоавть с разными

частями, PHP – Phython – Java - Go ...

Page 10: Рецепты RabbitMQ

Паттерны сообщений

Page 11: Рецепты RabbitMQ

Pipeline & Filter

Page 12: Рецепты RabbitMQ

Не совсем pipeline

ЗагрузкаYML

ПарсингYML

Загрузкакартинок

Page 13: Рецепты RabbitMQ

Publish-Subscriber Channel

Page 14: Рецепты RabbitMQ

Routers

Page 15: Рецепты RabbitMQ

AdvancedMessageQueueProtocol

Page 16: Рецепты RabbitMQ
Page 17: Рецепты RabbitMQ

Exchange

● Принимает сообщения

● Имеет имя

● Имеет тип:- fanout- direct- topic - headers

AMQP : Exchange (обмен)

Page 18: Рецепты RabbitMQ

Exchange

AMQP : Exchange (обмен)● Принимает сообщения

● Имеет имя

● Имеет тип

Имеет свойства:- autodelete- transit- durable

Page 19: Рецепты RabbitMQ

Exchange

AMQP : Exchange (обмен)

$exchange = new AMQPExchange($channel);$exchange->setName('MyExchange';)$exchange->declare();

Page 20: Рецепты RabbitMQ

AMQP : Queue (очередь)

Queue

● Отдает сообщения адресату по принципу FIFO

● Имеет имя● Имеет свойства:

- autodelete- durable- exclusive

Page 21: Рецепты RabbitMQ

AMQP : Queue (очередь)

Queue

$queue = new AMQPQueue($channel);$queue->setName('MyQueue');$queue->declare();

Page 22: Рецепты RabbitMQ

AMQP : Bind (связь)

● Между Exchange и Queue определяем связь (или маршрут): Bind

● Имеет ключ RoutingKey, в соответствии с которым определяется маршрут сообщения

QueueExchangeBind

Page 23: Рецепты RabbitMQ

AMQP : Bind (связь)

QueueExchangeBind

$queue = new AMQPQueue($channel);$queue->setName('MyQueue');$queue->bind('MyExchange', $key);

Page 24: Рецепты RabbitMQ

AMQP : Bind (связь)

QueueExchangeBind

$exchange = new AMQPExchange($channel);$exchange->setName('MyExchange');$exchange->bind('MyQueue', $key);

Page 25: Рецепты RabbitMQ

AMQP : Bind (связь)

QueueExchangeBind

$exchange = new AMQPExchange($channel);$exchange->setName('MyExchange');$exchange->bind('MyQueue', $key);

Объявляется один раз

Page 26: Рецепты RabbitMQ

AMQP : Internals

Page 27: Рецепты RabbitMQ

AMQP : Message

Page 28: Рецепты RabbitMQ

Exchange

Состоит:

● тела

● routing key

● заголовков

● имеет аттрибуты

AMQP : Message

Page 29: Рецепты RabbitMQ

● Expiration period

● Message publishing timeshamp

Exchange

Аттрибуты:

● Content-type

● Content-encoding

● Delivery-mode

● Message priority

● Application id

AMQP : Message

Page 30: Рецепты RabbitMQ

Exchange

AMQP : Message

В зависимости от типа Exchange и routingKey сообщения определяется маршрут сообщения

Queue 1

Queue 2

Page 31: Рецепты RabbitMQ

Exchange

AMQP : Message

Fanout – ключ не учитываем

Direct – полное совпадение

Topic – совпадение по маске

Queue 1

Queue 2

Page 32: Рецепты RabbitMQ
Page 33: Рецепты RabbitMQ

Exchange

AMQP : Message

Fanout – самый быстрый

Direct – середина на половине

Topic – сомый медленный

Queue 1

Queue 2

Page 34: Рецепты RabbitMQ

Exchange

Отправить сообщение

$exchange = new AMQPExchange($channel);$exchange->setName('MyExchange';)$exchange->publish($message, $key);

Page 35: Рецепты RabbitMQ

AMQP : ACK

QueueExchangeBind

На каждое принятое сообщение должна быть отослана “квитанция” ACK (Acknowledgements).

Page 36: Рецепты RabbitMQ

AMQP : ACK

QueueExchangeBind

На каждое принятое сообщение должна быть отослана “квитанция” ACK (Acknowledgements).

Если Очередь имеет св-во AUTOACK то подтверждение специально отправлять не нужно

ACK

Page 37: Рецепты RabbitMQ

Guaranteed Delivery

Page 38: Рецепты RabbitMQ

AMQP : ACK

workerWEB

Заказ

Page 39: Рецепты RabbitMQ

AMQP : ACK

workerWEB

Заказ

ACK

Удачное соединение

Page 40: Рецепты RabbitMQ

AMQP : ACK

workerWEB

Заказ

Удачное соединениеНе удачнонесоединение

Делаем повторный запрос

Page 41: Рецепты RabbitMQ
Page 42: Рецепты RabbitMQ

Объявление очереди и обмена

// создание очереди, обмена и их привязки друг к другу. $rabbit = new AMQPConnection();$res = $rabbit->connect();

$channel = new AMQPChannel($rabbit);$exchange = new AMQPExchange($channel);$exchange->setFlags(AMQP_DURABLE);$exchange->setName('to_worker');$exchange->setType('direct');$exchange->declare();

$queue = new AMQPQueue($channel);$queue->setFlags(AMQP_DURABLE);$queue->setName('worker');

Page 43: Рецепты RabbitMQ

Объявление очереди и обмена

// создание очереди, обмена и их привязки друг к другу. $rabbit = new AMQPConnection();$res = $rabbit->connect();

$channel = new AMQPChannel($rabbit);$exchange = new AMQPExchange($channel);$exchange->setFlags(AMQP_DURABLE);$exchange->setName('to_worker');$exchange->setType('direct');$exchange->declare();

$queue = new AMQPQueue($channel);$queue->setFlags(AMQP_DURABLE);$queue->setName('worker');

AMQP_DURABLEAMQP_AUTODELETEAMQP_EXCLUSIVEAMQP_INTERNALAMQP_IMMEDIATEAMQP_AUTOACK

Page 44: Рецепты RabbitMQ

Объявление очереди и обмена

// создание очереди, обмена и их привязки друг к другу. $rabbit = new AMQPConnection();$res = $rabbit->connect();

$channel = new AMQPChannel($rabbit);$exchange = new AMQPExchange($channel);$exchange->setFlags(AMQP_DURABLE);$exchange->setName('to_worker');$exchange->setType('direct');$exchange->declare();

$queue = new AMQPQueue($channel);$queue->setFlags(AMQP_DURABLE);$queue->setName('worker');

AMQP_DURABLEAMQP_AUTODELETEAMQP_EXCLUSIVEAMQP_INTERNALAMQP_IMMEDIATEAMQP_AUTOACK

Это можно сделатьодин раз

Page 45: Рецепты RabbitMQ

Привзка очереди к обмену

$rabbit = new AMQPConnection();$res = $rabbit->connect();$channel = new AMQPChannel($rabbit);$queue = new AMQPQueue($channel);$queue->setName('worker');// $queue->declare();

$queue->bind('to_worker', 'logs');$rabbit->disconnect();

Page 46: Рецепты RabbitMQ

Привзка очереди к обмену

$rabbit = new AMQPConnection();$res = $rabbit->connect();$channel = new AMQPChannel($rabbit);$queue = new AMQPQueue($channel);$queue->setName('worker');// $queue->declare();

$queue->bind('to_worker', 'logs');$rabbit->disconnect();

Routing key

Page 47: Рецепты RabbitMQ

Привзка очереди к обмену

Это можно сделатьодин раз

Page 48: Рецепты RabbitMQ

Привзка очереди к обмену

$rabbit = new AMQPConnection();$res = $rabbit->connect();$channel = new AMQPChannel($rabbit);$queue = new AMQPQueue($channel);$queue->setName('worker');// $queue->declare();

$queue->bind('to_worker', 'logs');$rabbit->disconnect();

Это можно вообще не делать

а использоватьHTTP интерфейс

Page 49: Рецепты RabbitMQ

Публикация сообщения

$rabbit = new AMQPConnection();$res = $rabbit->connect();

$channel = new AMQPChannel($rabbit);$exchange = new AMQPExchange($channel);$exchange->setName('to_worker');$i=0;

while ($i < 20) { $i++; $data = json_encode([1,2,3, rand(0, 1000)]); $exchange->publish($data, 'logs', 0, ['delivery_mode'=>2, 'content_type'=> 'text/json'] );}

Page 50: Рецепты RabbitMQ

Публикация сообщения

$rabbit = new AMQPConnection();$res = $rabbit->connect();

$channel = new AMQPChannel($rabbit);$exchange = new AMQPExchange($channel);$exchange->setName('to_worker');$i=0;

while ($i < 20) { $i++; $data = json_encode([1,2,3, rand(0, 1000)]); $exchange->publish($data, 'logs', 0, ['delivery_mode'=>2, 'content_type'=> 'text/json'] );}

Routing key Persisten

Page 51: Рецепты RabbitMQ

Синхронное / Асинхронное

Page 52: Рецепты RabbitMQ

Асинхронное GET

$rabbit = new AMQPConnection(); $rabbit->connect();

$channel = new AMQPChannel($rabbit$queue = new AMQPQueue($channel); $queue->setName('worker'); $msg = $queue->get();

Page 53: Рецепты RabbitMQ

Асинхронное GET

Page 54: Рецепты RabbitMQ

Синхронное CONSUMEfunction processMessage($envelope, $queue) { echo 'Message: [', $envelope->getDeliveryTag(), ']', $envelope->getBody(),PHP_EOL; $queue->ack( $envelope->getDeliveryTag() );}

$rabbit = new AMQPConnection();$res = $rabbit->connect(); $channel = new AMQPChannel($rabbit);

$queue = new AMQPQueue($channel); $queue->setName('worker');$queue->setFlags(AMQP_EXCLUSIVE);$queue->consume("processMessage");

Page 55: Рецепты RabbitMQ

Синхронное CONSUMEfunction processMessage($envelope, $queue) { echo 'Message: [', $envelope->getDeliveryTag(), ']', $envelope->getBody(),PHP_EOL; $queue->ack( $envelope->getDeliveryTag() );}

$rabbit = new AMQPConnection();$res = $rabbit->connect(); $channel = new AMQPChannel($rabbit);

$queue = new AMQPQueue($channel); $queue->setName('worker');$queue->setFlags(AMQP_EXCLUSIVE);$queue->consume("processMessage");

Page 56: Рецепты RabbitMQ

function processMessage($envelope, $queue) { echo 'Message: [', $envelope->getDeliveryTag(), ']', $envelope->getBody(),PHP_EOL; $queue->ack( $envelope->getDeliveryTag() );}

$rabbit = new AMQPConnection();$res = $rabbit->connect(); $channel = new AMQPChannel($rabbit);

$queue = new AMQPQueue($channel); $queue->setName('worker');$queue->setFlags(AMQP_EXCLUSIVE);$queue->consume("processMessage");

Синхронное CONSUME

Page 57: Рецепты RabbitMQ

Асинхронное GET

Page 58: Рецепты RabbitMQ

Publish/Consume

Page 59: Рецепты RabbitMQ

Publish/Consume

В RannitMQработает не так как ожидается

Page 60: Рецепты RabbitMQ

Publish/Consume

ЗагрузкаYML

ПарсингYML

Загрузкакартинок

Page 61: Рецепты RabbitMQ

Publish/Consume

ЗагрузкаYML

ПарсингYML

Загрузкакартинок

50%

50%

Page 62: Рецепты RabbitMQ

Publish/Consume

ЗагрузкаYML

ПарсингYML

Загрузкакартинок

50%

50%

Потеря 50% контента

Page 63: Рецепты RabbitMQ

Publish/Consume

ЗагрузкаYML

Загрузкакартинок

Загрузкакартинок

50%

50%

Page 64: Рецепты RabbitMQ

Publish/Consume

ЗагрузкаYML

Загрузкакартинок

Загрузкакартинок

33.3%

33.3%

33.3%Загрузкакартинок

Page 65: Рецепты RabbitMQ

Publish/Consume

ЗагрузкаYML

ПарсингYML

Загрузкакартинок

Channel -1

Channel -2

Page 66: Рецепты RabbitMQ

Несколько каналов

ПарсингYML

Загрузкакартинок

Channel -1

Channel -2

ЗагрузкаYML content

parsing

uploadingExchange: Content, funout, Bind: parsing durable Bind: uploading

Queue 1: parsing, durable

Queue 2: uploading, durable

Page 67: Рецепты RabbitMQ

Несколько каналов(вар 2)

ПарсингYML

Загрузкакартинок

Channel -1

Channel -2

ЗагрузкаYML content

parsing

uploadingExchange: Content, header, durable

Queue 1: parsing, durable

Queue 2: uploading, durable

Bind: operation:x-parsing Bind: operation:x-uploading

Page 68: Рецепты RabbitMQ

Несколько каналов(вар 2)

ПарсингYML

Загрузкакартинок

Channel -1

Channel -2

ЗагрузкаYML content

parsing

uploadingExchange: Content, header, durable

Queue 1: parsing, durable

Queue 2: uploading, durable

Bind: operation:x-parsing Bind: operation:x-uploading

Page 69: Рецепты RabbitMQ

Несколько каналов(вар 2)

ПарсингYML

Загрузкакартинок

Channel -1

Channel -2

ЗагрузкаYML content

parsing

uploadingExchange: Content, header, durable

Queue 1: parsing, durable

Queue 2: uploading, durable

Bind: operation:x-parsing Bind: operation:x-uploading

Page 70: Рецепты RabbitMQ

Несколько каналовimport pikaconnection = pika.BlockingConnection()ch = connection.channel()ch.queue_bind( exchange='content', queue='parser', arguments={'operation': 'parsing', 'x-match':'any'})

Page 71: Рецепты RabbitMQ

Несколько каналовimport pikaconnection = pika.BlockingConnection()ch = connection.channel()ch.queue_bind( exchange='content', queue='parser', arguments={'operation': 'parser', 'x-match':'any'})

в PHPНельзя задать

аргументы для Bind

Page 72: Рецепты RabbitMQ

Несколько каналов

$exchange = new AMQPExchange($channel);$exchange->setName('to_worker');$ex->setType(AMQP_EX_TYPE_HEADERS);

$data = json_encode([1,2,3]);$headers = ['operation' => 'parsing'];$args = [ 'content_type'=> 'text/json', 'headers' => $headers ];$exchange->publish($data,'work',0,$args);

Page 73: Рецепты RabbitMQ

Несколько каналов

$exchange = new AMQPExchange($channel);$exchange->setName('to_worker');$ex->setType(AMQP_EX_TYPE_HEADERS);

$data = json_encode([1,2,3]);$headers = ['operation' => 'parsing'];$args = [ 'content_type'=> 'text/json', 'headers' => $headers ];$exchange->publish($data,'work',0,$args);

Page 74: Рецепты RabbitMQ

Несколько каналов(вар 2)

Page 75: Рецепты RabbitMQ

Синхронное / Асинхронноеwhat is the question ?

WEB AJAX лучше асинхронное

WebSocket Синхронное

Page 76: Рецепты RabbitMQ

Синхронное / Асинхронное

WEB AJAX лучше асинхронное

AMQP REST https://github.com/akalend/amqp-rest

Page 77: Рецепты RabbitMQ

Синхронное / Асинхронное

WEB AJAX лучше асинхронное

AMQP REST https://github.com/akalend/amqp-rest

NGX-AMQP https://github.com/WPMedia/nginx-amqp

Page 78: Рецепты RabbitMQ

Синхронное / Асинхронное

WEB AJAX лучше асинхронное

AMQP REST https://github.com/akalend/amqp-rest

NGX-AMQP https://github.com/WPMedia/nginx-amqpНадо делать через Upstreem & subquery

Page 79: Рецепты RabbitMQ

Синхронное / Асинхронное

WEB AJAX лучше асинхронное

AMQP REST https://github.com/akalend/amqp-rest

NGX-AMQP https://github.com/WPMedia/nginx-amqp

NGX-RABBIT https://github.com/wingify/lua-resty-rabbitmqstomp

Page 80: Рецепты RabbitMQ

Синхронное / Асинхронное

WebSocket Синхронное

NGX-RABBIT https://github.com/wingify/lua-resty-rabbitmqstomp

Node.js

Page 81: Рецепты RabbitMQ

Routers

Page 82: Рецепты RabbitMQ

Exchange

Route Message

Direct – совпадение по ключу

● Bind Queue_1 logs

● Bind Queue_2 worker

Queue 1

Queue 2

Page 83: Рецепты RabbitMQ

Exchange

Route Message

Headers – совпадение по заголовку

● Bind Queue_1 {'operation' : 'logs', 'x-match':'any'}

● Bind Queue_2 {'operation' : 'worker' , 'x-match':'any'}

Queue 1

Queue 2

Page 84: Рецепты RabbitMQ

Messages

Page 85: Рецепты RabbitMQ

Варианты использования сообщений

Page 86: Рецепты RabbitMQ

Варианты использования сообщений

Page 87: Рецепты RabbitMQ

Паттерн: данные

workerWEB

Заказ

ПередачаЗаказа

Page 88: Рецепты RabbitMQ

Варианты использования сообщений

Page 89: Рецепты RabbitMQ

Загрузка видео с видео хостинга

LoadConvertWEB

Клиентскийскрипт

Получаем статусВыполнено

Curl

Page 90: Рецепты RabbitMQ

Channels

Page 91: Рецепты RabbitMQ

Poin-to-Point Channel

Page 92: Рецепты RabbitMQ

Poin-to-Point Channel

Exchange : durableQueue : durable, exclusive

Page 93: Рецепты RabbitMQ

Guaranteed Delivery

Page 94: Рецепты RabbitMQ

Guaranteed Delivery

Exchange : durable= 1Message : delivery-type = 2Queue : durable= 1, autodelete = 0, autoack = 1

Page 95: Рецепты RabbitMQ

Guaranteed Delivery

$delivery-tag = $message->delivery-tag;$queue->ack($delivery-tag);

Page 96: Рецепты RabbitMQ

Dead letter channel

Page 97: Рецепты RabbitMQ

Запасной канал

Page 98: Рецепты RabbitMQ

$exchange = new AMQPExchange($channel);$exchange->setFlags(AMQP_DURABLE);$exchange->setName('to_worker');$exchange->setType(AMQP_EX_TYPE_DIRECT);$exchange->declare();

$queue = new AMQPQueue($channel);$queue->setFlags(AMQP_AUTODELETE);$queue->setName('worker');$queue->declare();

$queue->bind('to_worker', 'work');$queue->setFlags(AMQP_DURABLE);$queue->setName('garbage');$queue->declare();$queue->bind('to_worker', 'work');

Запасной канал

Page 99: Рецепты RabbitMQ

Запасной канал

$queue->setName('worker');$queue->delete();$queue->setArgument('x-dead-letter-exchange','garbage');$queue->declare();$queue->bind('to_worker', 'work');

Page 100: Рецепты RabbitMQ

Request Reply

Page 101: Рецепты RabbitMQ

Correlation Identifier

Page 102: Рецепты RabbitMQ

Correlation Identifier

$cr_id = $message->getArgument('correlation_id');

$exchange->publish( $message, '', ['correlation_id=>$cr_id]);

Page 103: Рецепты RabbitMQ

Datatype channel

Page 104: Рецепты RabbitMQ

debugging

Page 105: Рецепты RabbitMQ

Debugging

Java -cp rabbitmq-client.jar:commons-io-1.2.jar:commons-cli-1.1.jar com.rabbitmq.tools.Tracer677

Page 106: Рецепты RabbitMQ

Rabbit MQ

2015 № 11

Кролик в песочнице

Page 107: Рецепты RabbitMQ

Rabbit MQ

2015 № 12

RabbitMQ. Вырастаем из штанишек.

Page 108: Рецепты RabbitMQ

книги

Page 109: Рецепты RabbitMQ

книги

Page 110: Рецепты RabbitMQ

книги

Page 111: Рецепты RabbitMQ

книги

Page 112: Рецепты RabbitMQ

Cпасибо за внимание