Queues with RabbitMQ

A presentation at IPC in October 2017 in Munich, Germany by Lorna Jane Mitchell

Slide 1

Slide 1

Queues With RabbitMQ Lorna Mitchell, IBM

Slide 2

Slide 2

Introducing Queues Use queues to: • asynchronously process tasks in your (existing) application • e.g. sending email, processing uploads • provide loose coupling points • e.g. delegate heavy tasks, split ownership/technology • enable parts of the system to scale appropriately • e.g. an event in one system causes a thousand other actions @lornajane

Slide 3

Slide 3

Queue Tools A selection of queue-ish tools • RabbitMQ* http://www.rabbitmq.com/ • Gearman http://gearman.org/ • Beanstalkd http://kr.github.io/beanstalkd/ • Kafka https://kafka.apache.org/ • Redis https://redis.io/ * RabbitMQ is used in today’s examples @lornajane

Slide 4

Slide 4

Getting To Know RabbitMQ @lornajane

Slide 5

Slide 5

Management Plugin https://www.rabbitmq.com/management.html @lornajane

Slide 6

Slide 6

Getting To Know RabbitMQ Some vocabulary • broker: the RabbitMQ instance • exchange: where to send the messages to • queue: where messages wait to be processed • binding key: rules for which messages go into this queue • message: the data to be processed • routing key: message route information • consumer: worker script to processes the messages @lornajane

Slide 7

Slide 7

RabbitMQ Exchanges Exchanges are the routing logic of RabbitMQ Messages go to exchanges and the exchanges put them into the correct queues for storage @lornajane

Slide 8

Slide 8

Types Of Exchange Direct: a given routing key puts messages onto the matching queue(s) Topic: queues are bound by key, and messages are routed to as many queues as their routing key matches Fanout: messages go to all queues bound to this exchange @lornajane

Slide 9

Slide 9

Default Exchange There is a default exchange in RabbitMQ Its name is ” and routing is on queue name @lornajane

Slide 10

Slide 10

RabbitMQ Queues Queues can: • have wildcards in binding keys • be durable (messages have their own durability) • have a maximum length • be configured with a “dead letter exchange” @lornajane

Slide 11

Slide 11

RabbitMQ Messages Messages have: • a body consisting of a string of data (JSON is common) • additional data, including TTL (Time To Live) and message durability • may have priority information @lornajane

Slide 12

Slide 12

RabbitMQ and PHP Sample code here: https://github.com/lornajane/queues-with-rabbitmq @lornajane

Slide 13

Slide 13

RabbitMQ and PHP Best library: https://github.com/php-amqplib/php-amqplib composer require php-amqplib/php-amqplib • dependencies include bcmath and mbstring @lornajane

Slide 14

Slide 14

Webhooks on GitHub @lornajane

Slide 15

Slide 15

Ngrok for Local Webhooks https://ngrok.com/ - secure tunnel to your dev platform Use this tool to: • webhook into code running locally • inspect the request and response of the webhook • replay requests and see the responses @lornajane

Slide 16

Slide 16

PHP Producer Receive webhooks from GitHub, add to queue 1 2 3 4 5 6 7 8 9 10 11 12 require “vendor/autoload.php”; $input = file_get_contents(“php://input”); $data = json_decode($input, true); $rabbit = new PhpAmqpLib\Connection\AMQPStreamConnection( ‘localhost’, 5672, ‘guest’, ‘guest’); $channel = $rabbit->channel(); $channel->queue_declare(‘pushes’, false, true, false, false); $message = new PhpAmqpLib\Message\AMQPMessage( $input, [“delivery_mode” => 2]); $channel->basic_publish($message, ”, ‘pushes’); @lornajane

Slide 17

Slide 17

PHP Consumer Process a queue with PHP 1 2 3 4 5 6 require “vendor/autoload.php”; $rabbit = new PhpAmqpLib\Connection\AMQPStreamConnection( ‘localhost’, 5672, ‘guest’, ‘guest’); $channel = $rabbit->channel(); $channel->queue_declare(‘pushes’, false, true, false, false); @lornajane

Slide 18

Slide 18

PHP Consumer Process a queue with PHP (continued) 1 2 3 4 5 6 7 8 9 10 11 $process = function ($message) { $data = json_decode($message->getBody(), true); // do message processing here $message->delivery_info[‘channel’]-> basic_ack($message->delivery_info[‘delivery_tag’]); }; $channel->basic_consume(‘pushes’, ”, false, false, false, false, $process); while(count($channel->callbacks)) { $channel->wait(); } @lornajane

Slide 19

Slide 19

Example App: Webhooks @lornajane

Slide 20

Slide 20

Example App: Webhooks (code: https://github.com/ibm-watson-data-lab/guestbook ) A simple guestbook application is extended to allow webhook notifications of new comments. @lornajane

Slide 21

Slide 21

Example App: Webhooks @lornajane

Slide 22

Slide 22

Example App: Webhooks @lornajane

Slide 23

Slide 23

Example App: Webhooks @lornajane

Slide 24

Slide 24

Example App: Webhooks @lornajane

Slide 25

Slide 25

Processing Messages @lornajane

Slide 26

Slide 26

Creating Workers Workers are disposable! • if things go wrong, exit • separate tool to monitor/restart as needed • beware long-running process hazards • everything processed “at least once” (but maybe more than once, and in any order…) @lornajane

Slide 27

Slide 27

Independent Workers @lornajane

Slide 28

Slide 28

Independent Workers For best results: • awesome, aggregated logging • monitoring: queue size, worker uptime, processing time • miniminum viable dependencies @lornajane

Slide 29

Slide 29

Completed Messages • acknowledge when messages are processed successfully • can acknowledge failure • reject the message • optionally: requeue @lornajane

Slide 30

Slide 30

Dead Letter Exchanges • reject without requeue • exceed TTL • queue length exceeded @lornajane

Slide 31

Slide 31

Retries Implement your own logic to handle retries Create a new message with: • all the existing message contents • plus some metadata such as retry count or backoff time @lornajane

Slide 32

Slide 32

Feedback Mechanisms Rabbit is fire-and-forget; work is delegated Common pattern: return queue to put updates into for the original producer then to consume. @lornajane

Slide 33

Slide 33

Example App: Webhooks @lornajane

Slide 34

Slide 34

Example App: Webhooks @lornajane

Slide 35

Slide 35

Queues With RabbitMQ @lornajane

Slide 36

Slide 36

Queues With RabbitMQ Queues are awesome for scalability and robustness RabbitMQ is open source, lightweight and fast Queues help us meet the requirements for modern applications @lornajane

Slide 37

Slide 37

Thanks! Resources: • RabbitMQ: https://www.rabbitmq.com/ • Try it: https://ibm.com/cloud • Blog: https://lornajane.net • Code: https://github.com/ibm-watson-data-lab/guestbook • @lornajane • lorna.mitchell@uk.ibm.com @lornajane