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

Рецепты RabbitMQ

Feb 12, 2017

Download

Internet

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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пасибо за внимание