Your SlideShare is downloading. ×
0
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
PHP, RabbitMQ, and You
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

PHP, RabbitMQ, and You

2,338

Published on

PHP, RabbitMQ, and You talk given at MidwestPHP 2014 …

PHP, RabbitMQ, and You talk given at MidwestPHP 2014

Video of the screens can be found here

http://www.youtube.com/watch?v=Nh5oFSXEg6k

This includes the videos of the sample code.

Published in: Technology
1 Comment
8 Likes
Statistics
Notes
  • How can I process callback in OOP, not only function but method of an object? I'm newbie in rabbitmq, esp amqp.

    Thanks
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
2,338
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
57
Comments
1
Likes
8
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. PHP, RabbitMQ, and You #mwphp14 #rabbitmq @jasonlotito MidwestPHP 2014 - RabbitMQ What will we be covering? 1. What is RabbitMQ 2. Technology Overview 3. Publishers 4. Consumers 5. Exchanges 6. Queues 7. Bindings 8. Carrot to make things easy 9. Publish events from the web 10.Multiple consumers 11.Management UI Publishing 12.Consumers Publishing
  • 2. PHP, RabbitMQ, and You #mwphp14 #rabbitmq @jasonlotito
  • 3. Jason Lotito Senior Architect @ MeetMe @jasonlotito.com github.com/jasonlotito@gmail.com ! Senior Architect means people can blame me when things don’t work as expected. When things work, it’s because they worked around my code.
  • 4. Who has worked with RabbitMQ in production? Raise your hands. The only audience participation part, I promise.
  • 5. Part 1 Crash Course In RabbitMQ 1. What is RabbitMQ 2. Technology Overview 3. Publishers 4. Consumers 5. Exchanges 6. Queues 7. Bindings
  • 6. – RabbitMQ In Action*, Manning “RabbitMQ is an open source message broker and queueing server that can be used to let disparate applications share data via a common protocol, or to simply queue jobs for processing by distributed workers. ”
  • 7. Where RabbitMQ Sits (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 8. Event Occurs in Application (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 9. Message is Sent to Exchange (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 10. Message is Sent to Queue (P) Producer/Publisher - (X) Exchange - (C) Consumer Exchanges connect to Queues through Bindings
  • 11. Message is Sent to Consumer (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 12. – Me, Now “Where as a database handles your data, a message queue handles your events.”
  • 13. A database handles nouns. A message queue handles verbs.
  • 14. But enough talk Let’s see some code!
  • 15. composer.json "require": {
 "videlalvaro/php-amqplib": "2.2.*"
 }
  • 16. We are starting with the publisher
  • 17. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 18. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 19. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 20. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 21. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 22. Now we create a consumer
  • 23. Consumer: receive.php <?php
 
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 $channel = $connection->channel();
 $channel->queue_declare('hello', false, false, false, true);
 
 echo ' [*] Waiting for messages. To exit press CTRL+C', "n";
 
 $handler = function($message) use($channel){
 echo sprintf('Message: %s' . PHP_EOL, $message->body);
 };
 
 $channel->basic_consume('hello', false, true, true, false, false, $handler);
 $channel->wait();
  • 24. Consumer: receive.php <?php
 
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 $channel = $connection->channel();
 $channel->queue_declare('hello', false, false, false, true);
 
 echo ' [*] Waiting for messages. To exit press CTRL+C', "n";
 
 $handler = function($message) use($channel){
 echo sprintf('Message: %s' . PHP_EOL, $message->body);
 };
 
 $channel->basic_consume('hello', false, true, true, false, false, $handler);
 $channel->wait();
  • 25. Consumer: receive.php <?php
 
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 $channel = $connection->channel();
 $channel->queue_declare('hello', false, false, false, true);
 
 echo ' [*] Waiting for messages. To exit press CTRL+C', "n";
 
 $handler = function($message) use($channel){
 echo sprintf('Message: %s' . PHP_EOL, $message->body);
 };
 
 $channel->basic_consume('hello', false, true, true, false, false, $handler);
 $channel->wait();
  • 26. Consumer: receive.php <?php
 
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 $channel = $connection->channel();
 $channel->queue_declare('hello', false, false, false, true);
 
 echo ' [*] Waiting for messages. To exit press CTRL+C', "n";
 
 $handler = function($message) use($channel){
 echo sprintf('Message: %s' . PHP_EOL, $message->body);
 };
 
 $channel->basic_consume('hello', false, true, true, false, false, $handler);
 $channel->wait();
  • 27. Message is Sent to Exchange (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 28. Exchange Types Direct, Fanout, and Topic
  • 29. Queue bound to many exchanges
  • 30. $msg = new AMQPMessage( $message );
 $channel->basic_publish($msg, '', ‘messages.new');
  • 31. * matches one word # matches zero or more words A word is delineated by . *, #, and .
  • 32. *.new messages.* NOT *.messages.* messages.new matches
  • 33. NOT spam.* spam.*.* spam.# spam.message.new matches
  • 34. Now Let’s Create an Exchange and a Queue
  • 35. Using the Management UI rabbitmq-plugins enable rabbitmq_management http://localhost:15672
  • 36. We’ve Created Everything Publishers, Exchanges, Bindings, Queues, and Consumers
  • 37. So what can we do with this?
  • 38. Part 2 PHP & RabbitMQ Together 1. Carrot to make things easy 2. Publish events from the web 3. Multiple consumers 4. Management UI Publishing 5. Consumers Publishing
  • 39. Carrot github.com/jasonlotito/Carrot
  • 40. Carrot Consumer Code <?php
 require_once 'vendor/autoload.php';
 
 use CarrotConsumer; $queue = 'new_messages';
 $handler = function($msg){
 echo $msg, PHP_EOL;
 return true;
 }; 
 (new Consumer())->listenTo($queue, $handler)
 ->listenAndWait();!
  • 41. Carrot Publisher Code <?php
 require 'vendor/autoload.php';
 
 use CarrotPublisher;
 
 $msg = implode(' ', array_splice($argv, 1));
 (new Publisher('messages'))
 ->publish('message.new', $msg);
  • 42. Make publishing easy
  • 43. Make consuming easier
  • 44. github.com/jasonlotito/ midwest-rabbitmq/tree/carrot
  • 45. Adding the Web
  • 46. Publisher $publisher = new Publisher('messages');
 $sendCount = (int) (isset($_POST['simulatedMessageCount']) ? $_POST['simulatedMessageCount'] : 1);
 
 for($x = 0; $x<$sendCount; $x++){
 if(isset($_POST['simulateWork'])) {
 usleep(500000);
 $msg = ['comment' => $_POST['comment'] . " $x"];
 $publisher->eventuallyPublish('message.new', $msg);
 } else {
 $msg = ['comment' => $_POST['comment'] . " $x"];
 $publisher->publish('message.new', $msg);
 }
 }
  • 47. Let’s use the written Carrot Consumer Code
  • 48. batch_basic_publish public function eventuallyPublish($routingKey, $message)
 {
 $msg = $this->buildMessage($message);
 $channel = $this->getChannel();
 $channel->batch_basic_publish($msg, $this->exchange, $routingKey);
 $this->registerShutdownHandler();
 }
 
 public function finallyPublish()
 {
 if ($this->doBatchPublish) {
 $this->doBatchPublish = false;
 $this->getChannel()->publish_batch();
 }
 } ! // register finallyPublish private function registerShutdownHandler();

  • 49. Publish from the web Let’s add another consumer Without changing existing code
  • 50. send text messages $queueName = 'messages_for_nexmo';
 
 (new Consumer())
 ->bind($queueName, 'messages', 'message.new')
 ->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber) {
 $msg = json_decode($msg);
 $urlString = 'https://rest.nexmo.com/sms/json?api_key=%s&api_secret=%s' .
 '&from=17088568489&to=%s&text=%s';
 $preparedMessage = urlencode($msg->comment);
 $url = sprintf($urlString, $key, $secret, $phoneNumber, $preparedMessage);
 $res = file_get_contents($url);
 $result = json_decode($res);
 $messageResult = $result->messages[0];
 echo "Message Result: " .
 ($messageResult->status === '0' ? 'Message Sent' : 'Message not sent')
 . PHP_EOL;
 return $messageResult->status === '0';
 })->listenAndWait();

  • 51. send text messages $queueName = 'messages_for_nexmo';
 
 (new Consumer())
 ->bind($queueName, 'messages', 'message.new')
 ->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber) {
 $msg = json_decode($msg);
 $urlString = 'https://rest.nexmo.com/sms/json?api_key=%s&api_secret=%s' .
 '&from=17088568489&to=%s&text=%s';
 $preparedMessage = urlencode($msg->comment);
 $url = sprintf($urlString, $key, $secret, $phoneNumber, $preparedMessage);
 $res = file_get_contents($url);
 $result = json_decode($res);
 $messageResult = $result->messages[0];
 echo "Message Result: " .
 ($messageResult->status === '0' ? 'Message Sent' : 'Message not sent')
 . PHP_EOL;
 return $messageResult->status === '0';
 })->listenAndWait();

  • 52. send text messages $queueName = 'messages_for_nexmo';
 
 (new Consumer())
 ->bind($queueName, 'messages', 'message.new')
 ->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber) {
 $msg = json_decode($msg);
 $urlString = 'https://rest.nexmo.com/sms/json?api_key=%s&api_secret=%s' .
 '&from=17088568489&to=%s&text=%s';
 $preparedMessage = urlencode($msg->comment);
 $url = sprintf($urlString, $key, $secret, $phoneNumber, $preparedMessage);
 $res = file_get_contents($url);
 $result = json_decode($res);
 $messageResult = $result->messages[0];
 echo "Message Result: " .
 ($messageResult->status === '0' ? 'Message Sent' : 'Message not sent')
 . PHP_EOL;
 return $messageResult->status === '0';
 })->listenAndWait();

  • 53. Both queues get the message
  • 54. Let’s add another layer
  • 55. Yo dawg, let’s have a consumer publish
  • 56. Send an email After the text message
  • 57. Create a new Exchange
  • 58. Update text message consumer $publisher = new Publisher('sms');
 
 (new Consumer())
 ->bind($queueName, 'messages', 'message.new')
 ->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber, $publisher) {
 // existing code
 $successful = $messageResult->status === '0';
 
 if ($successful) {
 $publisher->publish(‘sms.sent', ['message' => $msg->comment]);
 }
 
 return $successful;
 })->listenAndWait();

  • 59. Let’s write the email consumer And I’ll also show you how to easily test them
  • 60. Email Consumer (new Consumer())
 ->bind('send_email', 'emails', '*.send')
 ->bind('send_email', 'sms', '*.sent')
 ->listenTo('send_email', function($message){
 $msg = json_decode($message);
 mail('jasonlotito@gmail.com', 'MidwestPHP RabbitMQ Talk', $msg->message);
 echo 'Message sent: ' . $msg->message . PHP_EOL;
 return true;
 })->listenAndWait();
  • 61. Email consumer (new Consumer())
 ->bind('send_email', 'emails', '*.send')
 ->bind('send_email', 'sms', '*.sent')
 ->listenTo('send_email', function($message){
 $msg = json_decode($message);
 mail('jasonlotito@gmail.com', 'MidwestPHP RabbitMQ Talk', $msg->message);
 echo 'Message sent: ' . $msg->message . PHP_EOL;
 return true;
 })->listenAndWait();
  • 62. Now, let’s see it from the beginning
  • 63. rabbitmq.org
  • 64. Thank you. Review: joind.in/10558 #midwestphp #rabbitmq Questions? Feel free to stop and ask me, email, tweet, @jasonlotito@gmail.com

×