SlideShare une entreprise Scribd logo
1  sur  117
Télécharger pour lire hors ligne
Scaling Web Apps
With RabbitMQ
ÁlvaroVidela | The NetCircle
Erlang Factory Lite 2010
Who?
About Me
• Development Manager at TheNetCircle.com
• Writing “RabbitMQ in Action” for Manning
• Blog: http://videlalvaro.github.com/
• Twitter: @old_sound
Why Do I need
RabbitMQ?
The User
I don’t want to wait
till your app resizes
my image!
The Product Owner
Can we also notify the
user friends when she
uploads a new image?
Can we also notify the
user friends when she
uploads a new image?
I forgot to mention we need it for tomorrow…
The Sysadmin
Dumb!You’re delivering
full size images!
The bandwidth bill has
tripled!
Dumb!You’re delivering
full size images!
The bandwidth bill has
tripled!
We need this fixed for yesterday!
The Developer in the
other team
I need to call your PHP
stuff but from Python
I need to call your PHP
stuff but from Python
And also Java starting next week
You
FML!
Is there a solution?
RabbitMQ & AMQP
AMQP
AMQP
• Advanced Message Queuing Protocol
• Suits Interoperability
• Completely Open Protocol
• Binary Protocol
• AMQP Model
• AMQP Wire Format
AMQP Model
• Exchanges
• Message Queues
• Bindings
• Rules for binding them
AMQP Wire Protocol
• Functional Layer
• Transport Layer
Message Flow
http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Messaging_Tutorial/chap-Messaging_Tutorial-Initial_Concepts.html
Exchange Types
• Fanout
• Direct
• Topic
http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Messaging_Tutorial/sect-Messaging_Tutorial-Initial_Concepts-
Fanout_Exchange.html
http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Messaging_Tutorial/sect-Messaging_Tutorial-Initial_Concepts-
Direct_Exchange.html
http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Messaging_Tutorial/sect-Messaging_Tutorial-Initial_Concepts-
Topic_Exchange.html
Usage Scenarios
Usage Scenarios
• Batch Processing
Usage Scenarios
• Batch Processing
• Image Uploading
Usage Scenarios
• Batch Processing
• Image Uploading
• Distributed Logging
Scenario
Batch Processing
Requirements
Requirements
• Generate XML
Requirements
• Generate XML
• Distribution Over a Cluster
Requirements
• Generate XML
• Distribution Over a Cluster
• Elasticity - Add/Remove new workers
Requirements
• Generate XML
• Distribution Over a Cluster
• Elasticity - Add/Remove new workers
• No Code Changes
Design
Publisher Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$msg = new AMQPMessage($video_info,
array('content_type' => 'text/plain',
'delivery_mode' => 2));
$channel->basic_publish($msg, 'video-desc-ex');
$channel->close();
$conn->close();
Publisher Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$msg = new AMQPMessage($video_info,
array('content_type' => 'text/plain',
'delivery_mode' => 2));
$channel->basic_publish($msg, 'video-desc-ex');
$channel->close();
$conn->close();
Publisher Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$msg = new AMQPMessage($video_info,
array('content_type' => 'text/plain',
'delivery_mode' => 2));
$channel->basic_publish($msg, 'video-desc-ex');
$channel->close();
$conn->close();
Publisher Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$msg = new AMQPMessage($video_info,
array('content_type' => 'text/plain',
'delivery_mode' => 2));
$channel->basic_publish($msg, 'video-desc-ex');
$channel->close();
$conn->close();
Publisher Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$msg = new AMQPMessage($video_info,
array('content_type' => 'text/plain',
'delivery_mode' => 2));
$channel->basic_publish($msg, 'video-desc-ex');
$channel->close();
$conn->close();
Publisher Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$msg = new AMQPMessage($video_info,
array('content_type' => 'text/plain',
'delivery_mode' => 2));
$channel->basic_publish($msg, 'video-desc-ex');
$channel->close();
$conn->close();
Consumer Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$channel->queue_declare('video-desc-queue', false, true,
false, false);
$channel->queue_bind('video-desc-queue', 'video-desc-ex');
$channel->basic_consume('video-desc-queue', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$channel->queue_declare('video-desc-queue', false, true,
false, false);
$channel->queue_bind('video-desc-queue', 'video-desc-ex');
$channel->basic_consume('video-desc-queue', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$channel->queue_declare('video-desc-queue', false, true,
false, false);
$channel->queue_bind('video-desc-queue', 'video-desc-ex');
$channel->basic_consume('video-desc-queue', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$channel->queue_declare('video-desc-queue', false, true,
false, false);
$channel->queue_bind('video-desc-queue', 'video-desc-ex');
$channel->basic_consume('video-desc-queue', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$channel->queue_declare('video-desc-queue', false, true,
false, false);
$channel->queue_bind('video-desc-queue', 'video-desc-ex');
$channel->basic_consume('video-desc-queue', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$channel->queue_declare('video-desc-queue', false, true,
false, false);
$channel->queue_bind('video-desc-queue', 'video-desc-ex');
$channel->basic_consume('video-desc-queue', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$channel = $conn->channel();
$channel->exchange_declare('video-desc-ex', 'direct', false,
true, false);
$channel->queue_declare('video-desc-queue', false, true,
false, false);
$channel->queue_bind('video-desc-queue', 'video-desc-ex');
$channel->basic_consume('video-desc-queue', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Scenario
Upload Pictures
Requirements
Requirements
• Upload Picture
Requirements
• Upload Picture
• Reward User
Requirements
• Upload Picture
• Reward User
• Notify User Friends
Requirements
• Upload Picture
• Reward User
• Notify User Friends
• Resize Picture
Requirements
• Upload Picture
• Reward User
• Notify User Friends
• Resize Picture
• No Code Changes
Design
Design
Design
Publisher Code
$channel->exchange_declare('upload-pictures', 'fanout', false,
true, false);
$metadata = json_encode(array(
'image_id' => $image_id,
'user_id' => $user_id,
‘image_path' => $image_path));
$msg = new AMQPMessage($metadata, array('content_type' =>
'application/json', 'delivery_mode' => 2));
$channel->basic_publish($msg, 'upload-pictures');
Publisher Code
$channel->exchange_declare('upload-pictures', 'fanout', false,
true, false);
$metadata = json_encode(array(
'image_id' => $image_id,
'user_id' => $user_id,
‘image_path' => $image_path));
$msg = new AMQPMessage($metadata, array('content_type' =>
'application/json', 'delivery_mode' => 2));
$channel->basic_publish($msg, 'upload-pictures');
Publisher Code
$channel->exchange_declare('upload-pictures', 'fanout', false,
true, false);
$metadata = json_encode(array(
'image_id' => $image_id,
'user_id' => $user_id,
‘image_path' => $image_path));
$msg = new AMQPMessage($metadata, array('content_type' =>
'application/json', 'delivery_mode' => 2));
$channel->basic_publish($msg, 'upload-pictures');
Publisher Code
$channel->exchange_declare('upload-pictures', 'fanout', false,
true, false);
$metadata = json_encode(array(
'image_id' => $image_id,
'user_id' => $user_id,
‘image_path' => $image_path));
$msg = new AMQPMessage($metadata, array('content_type' =>
'application/json', 'delivery_mode' => 2));
$channel->basic_publish($msg, 'upload-pictures');
Publisher Code
$channel->exchange_declare('upload-pictures', 'fanout', false,
true, false);
$metadata = json_encode(array(
'image_id' => $image_id,
'user_id' => $user_id,
‘image_path' => $image_path));
$msg = new AMQPMessage($metadata, array('content_type' =>
'application/json', 'delivery_mode' => 2));
$channel->basic_publish($msg, 'upload-pictures');
Consumer Code
$channel->exchange_declare('upload-pictures', 'fanout',
false, true, false);
$channel->queue_declare('resize-picture', false, true,
false, false);
$channel->queue_bind('resize-picture', 'upload-pictures');
$channel->basic_consume('resize-picture', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$channel->exchange_declare('upload-pictures', 'fanout',
false, true, false);
$channel->queue_declare('resize-picture', false, true,
false, false);
$channel->queue_bind('resize-picture', 'upload-pictures');
$channel->basic_consume('resize-picture', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$channel->exchange_declare('upload-pictures', 'fanout',
false, true, false);
$channel->queue_declare('resize-picture', false, true,
false, false);
$channel->queue_bind('resize-picture', 'upload-pictures');
$channel->basic_consume('resize-picture', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$channel->exchange_declare('upload-pictures', 'fanout',
false, true, false);
$channel->queue_declare('resize-picture', false, true,
false, false);
$channel->queue_bind('resize-picture', 'upload-pictures');
$channel->basic_consume('resize-picture', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$channel->exchange_declare('upload-pictures', 'fanout',
false, true, false);
$channel->queue_declare('resize-picture', false, true,
false, false);
$channel->queue_bind('resize-picture', 'upload-pictures');
$channel->basic_consume('resize-picture', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$channel->exchange_declare('upload-pictures', 'fanout',
false, true, false);
$channel->queue_declare('resize-picture', false, true,
false, false);
$channel->queue_bind('resize-picture', 'upload-pictures');
$channel->basic_consume('resize-picture', $consumer_tag,
false, false, false, false, $consumer);
while(count($channel->callbacks)) {
$channel->wait();
}
Consumer Code
$consumer = function($msg){
$meta = json_decode($msg->body, true);
	
resize_picture($meta['image_id'], $meta['image_path']);
	
$msg->delivery_info['channel']->
basic_ack($msg->delivery_info['delivery_tag']);
};
Consumer Code
$consumer = function($msg){
$meta = json_decode($msg->body, true);
	
resize_picture($meta['image_id'], $meta['image_path']);
	
$msg->delivery_info['channel']->
basic_ack($msg->delivery_info['delivery_tag']);
};
Consumer Code
$consumer = function($msg){
$meta = json_decode($msg->body, true);
	
resize_picture($meta['image_id'], $meta['image_path']);
	
$msg->delivery_info['channel']->
basic_ack($msg->delivery_info['delivery_tag']);
};
Consumer Code
$consumer = function($msg){
$meta = json_decode($msg->body, true);
	
resize_picture($meta['image_id'], $meta['image_path']);
	
$msg->delivery_info['channel']->
basic_ack($msg->delivery_info['delivery_tag']);
};
Consumer Code
$consumer = function($msg){
$meta = json_decode($msg->body, true);
	
resize_picture($meta['image_id'], $meta['image_path']);
	
$msg->delivery_info['channel']->
basic_ack($msg->delivery_info['delivery_tag']);
};
Scenario
Distributed Logging
Requirements
Requirements
• Several Web Servers
Requirements
• Several Web Servers
• Logic Separated by Module/Action
Requirements
• Several Web Servers
• Logic Separated by Module/Action
• Several Log Levels:
Requirements
• Several Web Servers
• Logic Separated by Module/Action
• Several Log Levels:
• Info,Warning, Error
Requirements
• Several Web Servers
• Logic Separated by Module/Action
• Several Log Levels:
• Info,Warning, Error
• Add/Remove log listeners at will
Design
Design
Design
Design
Design
Publisher Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$msg = new AMQPMessage('some log message',
array('content_type' => 'text/plain'));
$channel->basic_publish($msg, 'logs',
'server1.user.profile.info');
Publisher Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$msg = new AMQPMessage('some log message',
array('content_type' => 'text/plain'));
$channel->basic_publish($msg, 'logs',
server1.user.profile.info');
Publisher Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$msg = new AMQPMessage('some log message',
array('content_type' => 'text/plain'));
$channel->basic_publish($msg, 'logs',
server1.user.profile.info');
Publisher Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$msg = new AMQPMessage('some log message',
array('content_type' => 'text/plain'));
$channel->basic_publish($msg, 'logs',
server1.user.profile.info');
Consumer Code
Get messages sent by host:
server1
Consumer Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$channel->queue_declare('server1-logs', false, true,
false, false);
$channel->queue_bind('server1-logs', 'logs', 'server1.#');
Consumer Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$channel->queue_declare('server1-logs', false, true,
false, false);
$channel->queue_bind('server1-logs', 'logs', 'server1.#');
Consumer Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$channel->queue_declare('server1-logs', false, true,
false, false);
$channel->queue_bind('server1-logs', 'logs', 'server1.#');
Consumer Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$channel->queue_declare('server1-logs', false, true,
false, false);
$channel->queue_bind('server1-logs', 'logs', 'server1.#');
Consumer Code
Get all error messages
Consumer Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$channel->queue_declare('error-logs', false, true,
false, false);
$channel->queue_bind('error-logs', 'logs', '#.error');
Consumer Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$channel->queue_declare('error-logs', false, true,
false, false);
$channel->queue_bind('error-logs', 'logs', '#.error');
Consumer Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$channel->queue_declare('error-logs', false, true,
false, false);
$channel->queue_bind('error-logs', 'logs', '#.error');
Consumer Code
$channel->exchange_declare('logs', 'topic', false,
true, false);
$channel->queue_declare('error-logs', false, true,
false, false);
$channel->queue_bind('error-logs', 'logs', '#.error');
Why RabbitMQ?
RabbitMQ
• Enterprise Messaging System
• Open Source MPL
• Written in Erlang/OTP
• Commercial Support
Features
• Reliable and High Scalable
• Easy To install
• Easy To Cluster
• Runs on:Windows, Solaris, Linux, OSX
• AMQP 0.8 - 0.9.1
Client Libraries
• Java
• .NET/C#
• Erlang
• Ruby, Python, PHP, Perl,AS3, Lisp, Scala,
Clojure, Haskell
Docs/Support
• http://www.rabbitmq.com/documentation.html
• http://dev.rabbitmq.com/wiki/
• #rabbitmq at irc.freenode.net
• http://www.rabbitmq.com/email-archive.html
One Setup for HA
Conclusion
Conclusion
• Flexibility
Conclusion
• Flexibility
• Scalability
Conclusion
• Flexibility
• Scalability
• Interoperability
Conclusion
• Flexibility
• Scalability
• Interoperability
• Reduce Ops
Questions?
Thanks!
Álvaro Videla
http://twitter.com/old_sound
http://github.com/videlalvaro
http://github.com/tnc
http://www.slideshare.net/old_sound

Contenu connexe

Similaire à Scaling Web Apps With RabbitMQ - Erlang Factory Lite

Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet ModulesPuppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
clkao
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
unodelostrece
 
Socket applications
Socket applicationsSocket applications
Socket applications
João Moura
 

Similaire à Scaling Web Apps With RabbitMQ - Erlang Factory Lite (20)

Practical Message Queueing using RabbitMQ (Nomad PHP EU Dec 2014)
Practical Message Queueing using RabbitMQ (Nomad PHP EU Dec 2014)Practical Message Queueing using RabbitMQ (Nomad PHP EU Dec 2014)
Practical Message Queueing using RabbitMQ (Nomad PHP EU Dec 2014)
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
 
PHP, RabbitMQ, and You
PHP, RabbitMQ, and YouPHP, RabbitMQ, and You
PHP, RabbitMQ, and You
 
Integrating php withrabbitmq_zendcon
Integrating php withrabbitmq_zendconIntegrating php withrabbitmq_zendcon
Integrating php withrabbitmq_zendcon
 
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet ModulesPuppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
Fewer cables
Fewer cablesFewer cables
Fewer cables
 
Email Using Plsql
Email Using PlsqlEmail Using Plsql
Email Using Plsql
 
Coffeescript - Getting Started
Coffeescript - Getting StartedCoffeescript - Getting Started
Coffeescript - Getting Started
 
Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)
 
99% is not enough
99% is not enough99% is not enough
99% is not enough
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
Deep dive in container service discovery
Deep dive in container service discoveryDeep dive in container service discovery
Deep dive in container service discovery
 
Paypal REST api ( Japanese version )
Paypal REST api ( Japanese version )Paypal REST api ( Japanese version )
Paypal REST api ( Japanese version )
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
VUG5: Varnish at Opera Software
VUG5: Varnish at Opera SoftwareVUG5: Varnish at Opera Software
VUG5: Varnish at Opera Software
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
How we use and deploy Varnish at Opera
How we use and deploy Varnish at OperaHow we use and deploy Varnish at Opera
How we use and deploy Varnish at Opera
 
Deploying Next Gen Systems with Zero Downtime
Deploying Next Gen Systems with Zero DowntimeDeploying Next Gen Systems with Zero Downtime
Deploying Next Gen Systems with Zero Downtime
 

Plus de Alvaro Videla

Rabbitmq Boot System
Rabbitmq Boot SystemRabbitmq Boot System
Rabbitmq Boot System
Alvaro Videla
 

Plus de Alvaro Videla (20)

Improvements in RabbitMQ
Improvements in RabbitMQImprovements in RabbitMQ
Improvements in RabbitMQ
 
Data Migration at Scale with RabbitMQ and Spring Integration
Data Migration at Scale with RabbitMQ and Spring IntegrationData Migration at Scale with RabbitMQ and Spring Integration
Data Migration at Scale with RabbitMQ and Spring Integration
 
RabbitMQ Data Ingestion at Craft Conf
RabbitMQ Data Ingestion at Craft ConfRabbitMQ Data Ingestion at Craft Conf
RabbitMQ Data Ingestion at Craft Conf
 
Unit Test + Functional Programming = Love
Unit Test + Functional Programming = LoveUnit Test + Functional Programming = Love
Unit Test + Functional Programming = Love
 
RabbitMQ Data Ingestion
RabbitMQ Data IngestionRabbitMQ Data Ingestion
RabbitMQ Data Ingestion
 
Dissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal ArchitectureDissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal Architecture
 
Introduction to RabbitMQ | Meetup at Pivotal Labs
Introduction to RabbitMQ | Meetup at Pivotal LabsIntroduction to RabbitMQ | Meetup at Pivotal Labs
Introduction to RabbitMQ | Meetup at Pivotal Labs
 
Writing testable code
Writing testable codeWriting testable code
Writing testable code
 
RabbitMQ Hands On
RabbitMQ Hands OnRabbitMQ Hands On
RabbitMQ Hands On
 
Rabbitmq Boot System
Rabbitmq Boot SystemRabbitmq Boot System
Rabbitmq Boot System
 
Cloud Foundry Bootcamp
Cloud Foundry BootcampCloud Foundry Bootcamp
Cloud Foundry Bootcamp
 
Cloud Messaging With Cloud Foundry
Cloud Messaging With Cloud FoundryCloud Messaging With Cloud Foundry
Cloud Messaging With Cloud Foundry
 
Taming the rabbit
Taming the rabbitTaming the rabbit
Taming the rabbit
 
Vertx
VertxVertx
Vertx
 
Código Fácil De Testear
Código Fácil De TestearCódigo Fácil De Testear
Código Fácil De Testear
 
Desacoplando aplicaciones
Desacoplando aplicacionesDesacoplando aplicaciones
Desacoplando aplicaciones
 
Messaging patterns
Messaging patternsMessaging patterns
Messaging patterns
 
Theres a rabbit on my symfony
Theres a rabbit on my symfonyTheres a rabbit on my symfony
Theres a rabbit on my symfony
 
Scaling webappswithrabbitmq
Scaling webappswithrabbitmqScaling webappswithrabbitmq
Scaling webappswithrabbitmq
 
Integrating RabbitMQ with PHP
Integrating RabbitMQ with PHPIntegrating RabbitMQ with PHP
Integrating RabbitMQ with PHP
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Dernier (20)

Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 

Scaling Web Apps With RabbitMQ - Erlang Factory Lite