SlideShare a Scribd company logo
1 of 62
Message Queueing
  from an MQ noob's perspective
Preamble

• I work for a global telco
• We push telco events and messages around
• All should be processed quickly and reliably
• Some generate a response
Scenario


• We send messages around in small text
  files, sometimes with RFC 2822 headers
• Use the UNIX sendf/recfiled mechanism
Problem


• It's entirely intolerant to faults
• ... and network latency
Our Solution


• Add in our own "message queueing"
• ... and some facilities to decouple delays
Shortcomings

• Messages cannot be sent to multiple hosts
• Target hosts are not easily reconfigurable
• It's developed in-house and has issues
Scenario

• multiple producers
• a consumer and its backup
• Systems separated by 100-400ms WAN
 • with occasional 100% packet loss
The Contenders
pymq

• very hazy on the details
• depends on MySQL? and Django?!?
• ignored while looking at kombu / rabbitmq
ZeroMQ aka 0MQ


"ZeroMQ is a message orientated IPC Library."
              - commenter on stackoverflow
AMQP
• Is a standard for message queueing
• Producers submit messages to brokers
• Brokers consist of exchanges and queues
• Exchanges route the messages
• Queues store messages
• Consumers pull messages out
RabbitMQ
RabbitMQ
Producer




              Broker




                       Consumer
RabbitMQ
Producer




                      Broker


           Exchange


                               Queue




                                       Consumer
RabbitMQ


Queues
RabbitMQ


Exchanges
RabbitMQ
RabbitMQ


Exchanges
RabbitMQ


 Routing
RabbitMQ


Exchange Types
RabbitMQ


Direct Exchanges
RabbitMQ


Topic Exchanges
RabbitMQ


Fanout Exchanges
RabbitMQ


Persistence
RabbitMQ


Broker Persistence
RabbitMQ


Message Persistence
RabbitMQ


1. Mark the exchange “durable”.
2. Mark the queue “durable”.
3. Set the message’s “delivery mode” to a value of 2
RabbitMQ


Persistence Warnings
My Desired Setup

   Remote Host                      Processing Server

         Publisher                          Queue
                              ebs
                     Interw

          Queue                           Consumer
My Desired Setup

   Remote Host                     Processing Server

        Publisher                          Queue

                             ebs
                    Interw
          Queue                          Consumer



        Consumer
My Desired Setup

   Remote Host                   Processing Server

        Publisher                      Consumer
                           ebs
                    Interw

          Queue
Shovel

Remote Host                      Processing Server

     Publisher                           Queue


                            bs
       Queue          rwe              Consumer
                 Inte


      Shovel
=ERROR REPORT==== 7-Aug-2012::16:50:32 ===
** Generic server <0.366.0> terminating
** Last message in was {'$gen_cast',init}
** When Server state == {state,undefined,undefined,undefined,undefined,
                  hello_shovel,
                  {shovel,
                   {endpoint,
                    [{amqp_params_direct,<<"guest">>,<<"/">>,
                      rabbit@localhost,none,[]}],
                    []},
                   {endpoint,
                    [{amqp_params_network,<<"guest">>,<<"guest">>,
                      <<>>,"hardrock",undefined,0,0,0,infinity,none,
                      [#Fun<amqp_auth_mechanisms.plain.3>,
                       #Fun<amqp_auth_mechanisms.amqplain.3>],
                      [],[]}],
                    []},
                   0,on_confirm,#Fun<rabbit_shovel_sup.16.91344538>,
                   #Fun<rabbit_shovel_sup.16.91344538>,<<"hello">>,5},
                  undefined,undefined,undefined,undefined,undefined}
** Reason for termination ==
** {{badmatch,{error,access_refused}},
   [{rabbit_shovel_worker,make_conn_and_chan,1,[]},
    {rabbit_shovel_worker,handle_cast,2,[]},
    {gen_server2,handle_msg,2,[]},
    {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,227}]}]}
error in config file "/usr/local/etc/rabbitmq/rabbitmq.config" (37): syntax error
before: '.'
Shovel
[
     {rabbitmq_shovel, [
        {shovels, [
           {hello_shovel, [
               {sources, [
                  {brokers, ["amqp://"]}
               ]}
             , {destinations, [
                  {brokers, ["amqp://server"]}
               ]}
             , {queue, <<"hello">>}
           ]}
        ]}
     ]}
].
[
                       Shovel
     {rabbitmq_shovel, [
        {shovels, [
           {hello_shovel, [
               {sources, [
                   {brokers, ["amqp://"]}
                 , {declarations, [
                       {'exchange.declare', [
                           {exchange, <<"foo">>}
                         , {type, <<"direct">>}
                         , durable
                       ]}
                     , {'queue.declare', [
                         {queue, <<"hello">>}
                       ]}
                     , {'queue.bind', [
                         {exchange, <<"foo">>}
                       , {queue, <<"hello">>}
                       ]}
                   ]}
               ]}
             , {destinations, [
                   {brokers, ["amqp://hardrock"]}
               ]}
             , {queue, <<"hello">>}
           ]}
        ]}
     ]}
].
Installation
• 1. install RabbitMQ
 • (install homebrew; brew install rabbitmq;
     rabbitmq-server [-detached])
  • (yum install rabbitmq-server.noarch)
  • rabbitmqctl or http://server:55672/
• 2. pip install kombu, or pika, or puka, or ...
pika


"a pure-Python implementation of the
       AMQP 0-9-1 protocol"
Publisher
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('server'))
channel = connection.channel()
channel.queue_declare(queue='hello', durable=True)
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!',
    properties=pika.BasicProperties(delivery_mode=2))
print " [x] Sent 'Hello World!'"
connection.close()




                            Publisher       Queue
Consumer
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))

channel = connection.channel()
channel.queue_declare(queue='hello', durable=True)

print ' [*] Waiting for messages. To exit press CTRL+C'

def callback(ch, method, properties, body):
    print ' [x] Received %r' % (body,)

channel.basic_consume(callback, queue='hello')

channel.start_consuming()

                            Queue             Consumer
Remote Consumer   Local Publisher
Remote queues
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('server'))

channel = connection.channel()
channel.queue_declare(queue='hello', durable=True)

print ' [*] Waiting for messages. To exit press CTRL+C'

def callback(ch, method, properties, body):
    print ' [x] Received %r' % (body,)

channel.basic_consume(callback, queue='hello')

channel.start_consuming()

                    Host 1               Host 2

                             Publisher             Queue



                             Consumer             Consumer
Remote Consumer   Local Consumer   Local Publisher
Issues

• pika's BlockingConnection (my use case is
  simple enough) hard-codes the socket
  timeout and fails to cope with latency >1s
• Fails to cope at all with packet loss
Deleting a Queue

import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('server'))
channel = connection.channel()
channel.queue_delete(queue='hello')
channel.close()
connection.close()
Kombu


"a messaging framework for Python"
Publisher

from kombu import BrokerConnection

with BrokerConnection('amqp://localhost') as conn:
    with conn.SimpleQueue('hello') as queue:
        queue.put('Hello World!')
        print " [x] Sent 'Hello World!'"
Bizarro errors


amqplib.client_0_8.exceptions.AMQPChannelException: (406,
u"PRECONDITION_FAILED - parameters for queue 'hello' in vhost '/'
not equivalent", (50, 10), 'Channel.queue_declare')
Publisher

from kombu import BrokerConnection

with BrokerConnection('amqp://localhost//') as conn:
    with conn.SimpleQueue('hello', queue_opts=dict(durable=False)) as queue:
        queue.put('Hello World!')
        print " [x] Sent 'Hello World!'"
Puka


"An opinionated RabbitMQ client"
Publisher

import puka

client = puka.Client('amqp://localhost//')
client.wait(client.connect())

client.wait(client.queue_declare(queue='hello', durable=True))

promise = client.basic_publish(exchange='', routing_key='hello',
    body='Hello World!')
client.wait(promise)
print " [x] Sent 'Hello World!'"

client.wait(client.close())
Other Plugins

• Management (web interface, quite nice)
• Federation (Shovel, but with MOAR)
• STOMP protocol support
STOMP


Simple (or Streaming) Text Orientated
         Messaging Protocol
STOMP


 "simple"
STOMP

{rabbitmq_stomp, [
    {tcp_listeners, [
        {"127.0.0.1", 61613}
      , {"::1",    61613}
    ]}
  , {default_user, [
        {login, "guest"}
      , {passcode, "guest"}
    ]}
]}
stompclient

from stompclient import PublishClient

client = PublishClient('localhost', 61613)
client.connect()
client.send('/queue/hello', 'Hello, world!')
client.disconnect()
stompclient
from kombu import BrokerConnection

with BrokerConnection('amqp://localhost') as conn:
    with conn.SimpleQueue('hello') as queue:
        queue.put('Hello World!')
        print " [x] Sent 'Hello World!'"




   from stompclient import PublishClient

   client = PublishClient('localhost', 61613)
   client.connect()
   client.send('/queue/hello', 'Hello, world!')
   client.disconnect()
stompclient
  from stompclient import PublishClient

  client = PublishClient('localhost', 61613)
  client.connect()
  client.send('/queue/hello', 'Hello, world!')
  client.disconnect()




from stompclient import PublishClient

with PublishClient('localhost', 61613) as client:
    client.send('/queue/hello', 'Hello, world!')
Celery


"a synchronous or asynchronous task queue/job
 queue based on distributed message passing"
TcpCatcher
• TCP, SOCKS, HTTP(S) proxy & monitor
• Can introduce latency and transmission
  errors
• Understands HTTP and images
• Can debug/interfere/log SSL traffic
• Free: www.tcpcatcher.fr

More Related Content

What's hot

VUG5: Varnish at Opera Software
VUG5: Varnish at Opera SoftwareVUG5: Varnish at Opera Software
VUG5: Varnish at Opera SoftwareCosimo Streppone
 
Dissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal ArchitectureDissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal ArchitectureAlvaro Videla
 
Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012 Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012 Tom Croucher
 
Writing Redis in Python with asyncio
Writing Redis in Python with asyncioWriting Redis in Python with asyncio
Writing Redis in Python with asyncioJames Saryerwinnie
 
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...Ontico
 
Toster - Understanding the Rails Web Model and Scalability Options
Toster - Understanding the Rails Web Model and Scalability OptionsToster - Understanding the Rails Web Model and Scalability Options
Toster - Understanding the Rails Web Model and Scalability OptionsFabio Akita
 
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 OperaCosimo Streppone
 
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Brian Sam-Bodden
 
Scaling Ruby with Evented I/O - Ruby underground
Scaling Ruby with Evented I/O - Ruby undergroundScaling Ruby with Evented I/O - Ruby underground
Scaling Ruby with Evented I/O - Ruby undergroundOmer Gazit
 
Alfresco 2019 DevCon lightning talk alan davis
Alfresco 2019 DevCon lightning talk alan davisAlfresco 2019 DevCon lightning talk alan davis
Alfresco 2019 DevCon lightning talk alan davisAlan Davis
 
Combining the strength of erlang and Ruby
Combining the strength of erlang and RubyCombining the strength of erlang and Ruby
Combining the strength of erlang and RubyMartin Rehfeld
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stackBram Vogelaar
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015Fernando Hamasaki de Amorim
 
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operationsgrim_radical
 
Bootstrap your Cloud Infrastructure using puppet and hashicorp stack
Bootstrap your Cloud Infrastructure using puppet and hashicorp stackBootstrap your Cloud Infrastructure using puppet and hashicorp stack
Bootstrap your Cloud Infrastructure using puppet and hashicorp stackBram Vogelaar
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stackBram Vogelaar
 

What's hot (19)

VUG5: Varnish at Opera Software
VUG5: Varnish at Opera SoftwareVUG5: Varnish at Opera Software
VUG5: Varnish at Opera Software
 
Dissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal ArchitectureDissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal Architecture
 
Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012 Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012
 
Writing Redis in Python with asyncio
Writing Redis in Python with asyncioWriting Redis in Python with asyncio
Writing Redis in Python with asyncio
 
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
 
Toster - Understanding the Rails Web Model and Scalability Options
Toster - Understanding the Rails Web Model and Scalability OptionsToster - Understanding the Rails Web Model and Scalability Options
Toster - Understanding the Rails Web Model and Scalability Options
 
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
 
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
 
Scaling Ruby with Evented I/O - Ruby underground
Scaling Ruby with Evented I/O - Ruby undergroundScaling Ruby with Evented I/O - Ruby underground
Scaling Ruby with Evented I/O - Ruby underground
 
Alfresco 2019 DevCon lightning talk alan davis
Alfresco 2019 DevCon lightning talk alan davisAlfresco 2019 DevCon lightning talk alan davis
Alfresco 2019 DevCon lightning talk alan davis
 
Combining the strength of erlang and Ruby
Combining the strength of erlang and RubyCombining the strength of erlang and Ruby
Combining the strength of erlang and Ruby
 
At Scale With Style
At Scale With StyleAt Scale With Style
At Scale With Style
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stack
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
 
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operations
 
Test driven infrastructure
Test driven infrastructureTest driven infrastructure
Test driven infrastructure
 
Bootstrap your Cloud Infrastructure using puppet and hashicorp stack
Bootstrap your Cloud Infrastructure using puppet and hashicorp stackBootstrap your Cloud Infrastructure using puppet and hashicorp stack
Bootstrap your Cloud Infrastructure using puppet and hashicorp stack
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stack
 
Ømq & Services @ Chartboost
Ømq & Services @ ChartboostØmq & Services @ Chartboost
Ømq & Services @ Chartboost
 

Viewers also liked

Do More With Message Queue
Do More With Message QueueDo More With Message Queue
Do More With Message QueueHean Hong Leong
 
Redis as a message queue
Redis as a message queueRedis as a message queue
Redis as a message queueBrandon Lamb
 
unix interprocess communication
unix interprocess communicationunix interprocess communication
unix interprocess communicationguest4c9430
 
Easy enterprise application integration with RabbitMQ and AMQP
Easy enterprise application integration with RabbitMQ and AMQPEasy enterprise application integration with RabbitMQ and AMQP
Easy enterprise application integration with RabbitMQ and AMQPRabbit MQ
 
Data warehouse : Order Management
Data warehouse : Order ManagementData warehouse : Order Management
Data warehouse : Order ManagementKritiya Sangnitidaj
 
Life in a Queue - Using Message Queue with django
Life in a Queue - Using Message Queue with djangoLife in a Queue - Using Message Queue with django
Life in a Queue - Using Message Queue with djangoTareque Hossain
 
The Art of Message Queues - TEKX
The Art of Message Queues - TEKXThe Art of Message Queues - TEKX
The Art of Message Queues - TEKXMike Willbanks
 
Q4M - a high-performance message queue for MySQL
Q4M - a high-performance message queue for MySQLQ4M - a high-performance message queue for MySQL
Q4M - a high-performance message queue for MySQLKazuho Oku
 

Viewers also liked (13)

Message queues
Message queuesMessage queues
Message queues
 
Do More With Message Queue
Do More With Message QueueDo More With Message Queue
Do More With Message Queue
 
Redis as a message queue
Redis as a message queueRedis as a message queue
Redis as a message queue
 
unix interprocess communication
unix interprocess communicationunix interprocess communication
unix interprocess communication
 
Easy enterprise application integration with RabbitMQ and AMQP
Easy enterprise application integration with RabbitMQ and AMQPEasy enterprise application integration with RabbitMQ and AMQP
Easy enterprise application integration with RabbitMQ and AMQP
 
Django Celery
Django Celery Django Celery
Django Celery
 
Data visualization for e commerce of jcpenney
Data visualization for e commerce of jcpenneyData visualization for e commerce of jcpenney
Data visualization for e commerce of jcpenney
 
Data warehouse : Order Management
Data warehouse : Order ManagementData warehouse : Order Management
Data warehouse : Order Management
 
Life in a Queue - Using Message Queue with django
Life in a Queue - Using Message Queue with djangoLife in a Queue - Using Message Queue with django
Life in a Queue - Using Message Queue with django
 
The Art of Message Queues - TEKX
The Art of Message Queues - TEKXThe Art of Message Queues - TEKX
The Art of Message Queues - TEKX
 
Art Of Message Queues
Art Of Message QueuesArt Of Message Queues
Art Of Message Queues
 
Q4M - a high-performance message queue for MySQL
Q4M - a high-performance message queue for MySQLQ4M - a high-performance message queue for MySQL
Q4M - a high-performance message queue for MySQL
 
Inter Process Communication
Inter Process CommunicationInter Process Communication
Inter Process Communication
 

Similar to Message queueing

Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupKacper Gunia
 
Scaling application with RabbitMQ
Scaling application with RabbitMQScaling application with RabbitMQ
Scaling application with RabbitMQNahidul Kibria
 
Introduction to Marionette Collective
Introduction to Marionette CollectiveIntroduction to Marionette Collective
Introduction to Marionette CollectivePuppet
 
Servers with Event Machine - David Troy - RailsConf 2011
Servers with Event Machine - David Troy - RailsConf 2011Servers with Event Machine - David Troy - RailsConf 2011
Servers with Event Machine - David Troy - RailsConf 2011David Troy
 
Lindsay distributed geventzmq
Lindsay distributed geventzmqLindsay distributed geventzmq
Lindsay distributed geventzmqRobin Xiao
 
Scaling applications with RabbitMQ at SunshinePHP
Scaling applications with RabbitMQ   at SunshinePHPScaling applications with RabbitMQ   at SunshinePHP
Scaling applications with RabbitMQ at SunshinePHPAlvaro Videla
 
MessagePack Rakuten Technology Conference 2010
MessagePack Rakuten Technology Conference 2010MessagePack Rakuten Technology Conference 2010
MessagePack Rakuten Technology Conference 2010Sadayuki Furuhashi
 
LCA2014 - Introduction to Go
LCA2014 - Introduction to GoLCA2014 - Introduction to Go
LCA2014 - Introduction to Godreamwidth
 
Service discovery like a pro (presented at reversimX)
Service discovery like a pro (presented at reversimX)Service discovery like a pro (presented at reversimX)
Service discovery like a pro (presented at reversimX)Eran Harel
 
Service Delivery Assembly Line with Vagrant, Packer, and Ansible
Service Delivery Assembly Line with Vagrant, Packer, and AnsibleService Delivery Assembly Line with Vagrant, Packer, and Ansible
Service Delivery Assembly Line with Vagrant, Packer, and AnsibleIsaac Christoffersen
 
Getting Started with Couchbase Ruby
Getting Started with Couchbase RubyGetting Started with Couchbase Ruby
Getting Started with Couchbase RubySergey Avseyev
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Masahiro Nagano
 
Going real time with Socket.io
Going real time with Socket.ioGoing real time with Socket.io
Going real time with Socket.ioArnout Kazemier
 
DRb and Rinda
DRb and RindaDRb and Rinda
DRb and RindaMark
 
JUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBoxJUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBoxmarekgoldmann
 
Kamaelia Protocol Walkthrough
Kamaelia Protocol WalkthroughKamaelia Protocol Walkthrough
Kamaelia Protocol Walkthroughkamaelian
 

Similar to Message queueing (20)

RabbitMQ in Sprayer
RabbitMQ in SprayerRabbitMQ in Sprayer
RabbitMQ in Sprayer
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
 
Scaling application with RabbitMQ
Scaling application with RabbitMQScaling application with RabbitMQ
Scaling application with RabbitMQ
 
Introduction to Marionette Collective
Introduction to Marionette CollectiveIntroduction to Marionette Collective
Introduction to Marionette Collective
 
Servers with Event Machine - David Troy - RailsConf 2011
Servers with Event Machine - David Troy - RailsConf 2011Servers with Event Machine - David Troy - RailsConf 2011
Servers with Event Machine - David Troy - RailsConf 2011
 
Pycon - Python for ethical hackers
Pycon - Python for ethical hackers Pycon - Python for ethical hackers
Pycon - Python for ethical hackers
 
Lindsay distributed geventzmq
Lindsay distributed geventzmqLindsay distributed geventzmq
Lindsay distributed geventzmq
 
Scaling applications with RabbitMQ at SunshinePHP
Scaling applications with RabbitMQ   at SunshinePHPScaling applications with RabbitMQ   at SunshinePHP
Scaling applications with RabbitMQ at SunshinePHP
 
web3j Overview
web3j Overviewweb3j Overview
web3j Overview
 
MessagePack Rakuten Technology Conference 2010
MessagePack Rakuten Technology Conference 2010MessagePack Rakuten Technology Conference 2010
MessagePack Rakuten Technology Conference 2010
 
LCA2014 - Introduction to Go
LCA2014 - Introduction to GoLCA2014 - Introduction to Go
LCA2014 - Introduction to Go
 
Service discovery like a pro (presented at reversimX)
Service discovery like a pro (presented at reversimX)Service discovery like a pro (presented at reversimX)
Service discovery like a pro (presented at reversimX)
 
Service Delivery Assembly Line with Vagrant, Packer, and Ansible
Service Delivery Assembly Line with Vagrant, Packer, and AnsibleService Delivery Assembly Line with Vagrant, Packer, and Ansible
Service Delivery Assembly Line with Vagrant, Packer, and Ansible
 
Getting Started with Couchbase Ruby
Getting Started with Couchbase RubyGetting Started with Couchbase Ruby
Getting Started with Couchbase Ruby
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015
 
Going real time with Socket.io
Going real time with Socket.ioGoing real time with Socket.io
Going real time with Socket.io
 
DRb and Rinda
DRb and RindaDRb and Rinda
DRb and Rinda
 
JUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBoxJUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBox
 
tdc2012
tdc2012tdc2012
tdc2012
 
Kamaelia Protocol Walkthrough
Kamaelia Protocol WalkthroughKamaelia Protocol Walkthrough
Kamaelia Protocol Walkthrough
 

More from Richard Jones

Introduction to Game Programming
Introduction to Game ProgrammingIntroduction to Game Programming
Introduction to Game ProgrammingRichard Jones
 
Web micro-framework BATTLE!
Web micro-framework BATTLE!Web micro-framework BATTLE!
Web micro-framework BATTLE!Richard Jones
 
Intro to Game Programming
Intro to Game ProgrammingIntro to Game Programming
Intro to Game ProgrammingRichard Jones
 
Introduction to Game Programming Tutorial
Introduction to Game Programming TutorialIntroduction to Game Programming Tutorial
Introduction to Game Programming TutorialRichard Jones
 
State of Python (2010)
State of Python (2010)State of Python (2010)
State of Python (2010)Richard Jones
 
What's New In Python 2.6
What's New In Python 2.6What's New In Python 2.6
What's New In Python 2.6Richard Jones
 
What's New In Python 2.5
What's New In Python 2.5What's New In Python 2.5
What's New In Python 2.5Richard Jones
 
What's New In Python 2.4
What's New In Python 2.4What's New In Python 2.4
What's New In Python 2.4Richard Jones
 
Tkinter Does Not Suck
Tkinter Does Not SuckTkinter Does Not Suck
Tkinter Does Not SuckRichard Jones
 

More from Richard Jones (11)

Angboard
AngboardAngboard
Angboard
 
Don't do this
Don't do thisDon't do this
Don't do this
 
Introduction to Game Programming
Introduction to Game ProgrammingIntroduction to Game Programming
Introduction to Game Programming
 
Web micro-framework BATTLE!
Web micro-framework BATTLE!Web micro-framework BATTLE!
Web micro-framework BATTLE!
 
Intro to Game Programming
Intro to Game ProgrammingIntro to Game Programming
Intro to Game Programming
 
Introduction to Game Programming Tutorial
Introduction to Game Programming TutorialIntroduction to Game Programming Tutorial
Introduction to Game Programming Tutorial
 
State of Python (2010)
State of Python (2010)State of Python (2010)
State of Python (2010)
 
What's New In Python 2.6
What's New In Python 2.6What's New In Python 2.6
What's New In Python 2.6
 
What's New In Python 2.5
What's New In Python 2.5What's New In Python 2.5
What's New In Python 2.5
 
What's New In Python 2.4
What's New In Python 2.4What's New In Python 2.4
What's New In Python 2.4
 
Tkinter Does Not Suck
Tkinter Does Not SuckTkinter Does Not Suck
Tkinter Does Not Suck
 

Recently uploaded

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
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 Scriptwesley chun
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
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)wesley chun
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 

Recently uploaded (20)

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
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
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
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)
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

Message queueing

  • 1. Message Queueing from an MQ noob's perspective
  • 2. Preamble • I work for a global telco • We push telco events and messages around • All should be processed quickly and reliably • Some generate a response
  • 3. Scenario • We send messages around in small text files, sometimes with RFC 2822 headers • Use the UNIX sendf/recfiled mechanism
  • 4.
  • 5. Problem • It's entirely intolerant to faults • ... and network latency
  • 6. Our Solution • Add in our own "message queueing" • ... and some facilities to decouple delays
  • 7. Shortcomings • Messages cannot be sent to multiple hosts • Target hosts are not easily reconfigurable • It's developed in-house and has issues
  • 8. Scenario • multiple producers • a consumer and its backup • Systems separated by 100-400ms WAN • with occasional 100% packet loss
  • 10. pymq • very hazy on the details • depends on MySQL? and Django?!? • ignored while looking at kombu / rabbitmq
  • 11. ZeroMQ aka 0MQ "ZeroMQ is a message orientated IPC Library." - commenter on stackoverflow
  • 12. AMQP • Is a standard for message queueing • Producers submit messages to brokers • Brokers consist of exchanges and queues • Exchanges route the messages • Queues store messages • Consumers pull messages out
  • 13.
  • 15. RabbitMQ Producer Broker Consumer
  • 16. RabbitMQ Producer Broker Exchange Queue Consumer
  • 29. RabbitMQ 1. Mark the exchange “durable”. 2. Mark the queue “durable”. 3. Set the message’s “delivery mode” to a value of 2
  • 31. My Desired Setup Remote Host Processing Server Publisher Queue ebs Interw Queue Consumer
  • 32. My Desired Setup Remote Host Processing Server Publisher Queue ebs Interw Queue Consumer Consumer
  • 33. My Desired Setup Remote Host Processing Server Publisher Consumer ebs Interw Queue
  • 34. Shovel Remote Host Processing Server Publisher Queue bs Queue rwe Consumer Inte Shovel
  • 35. =ERROR REPORT==== 7-Aug-2012::16:50:32 === ** Generic server <0.366.0> terminating ** Last message in was {'$gen_cast',init} ** When Server state == {state,undefined,undefined,undefined,undefined, hello_shovel, {shovel, {endpoint, [{amqp_params_direct,<<"guest">>,<<"/">>, rabbit@localhost,none,[]}], []}, {endpoint, [{amqp_params_network,<<"guest">>,<<"guest">>, <<>>,"hardrock",undefined,0,0,0,infinity,none, [#Fun<amqp_auth_mechanisms.plain.3>, #Fun<amqp_auth_mechanisms.amqplain.3>], [],[]}], []}, 0,on_confirm,#Fun<rabbit_shovel_sup.16.91344538>, #Fun<rabbit_shovel_sup.16.91344538>,<<"hello">>,5}, undefined,undefined,undefined,undefined,undefined} ** Reason for termination == ** {{badmatch,{error,access_refused}}, [{rabbit_shovel_worker,make_conn_and_chan,1,[]}, {rabbit_shovel_worker,handle_cast,2,[]}, {gen_server2,handle_msg,2,[]}, {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,227}]}]}
  • 36. error in config file "/usr/local/etc/rabbitmq/rabbitmq.config" (37): syntax error before: '.'
  • 37. Shovel [ {rabbitmq_shovel, [ {shovels, [ {hello_shovel, [ {sources, [ {brokers, ["amqp://"]} ]} , {destinations, [ {brokers, ["amqp://server"]} ]} , {queue, <<"hello">>} ]} ]} ]} ].
  • 38. [ Shovel {rabbitmq_shovel, [ {shovels, [ {hello_shovel, [ {sources, [ {brokers, ["amqp://"]} , {declarations, [ {'exchange.declare', [ {exchange, <<"foo">>} , {type, <<"direct">>} , durable ]} , {'queue.declare', [ {queue, <<"hello">>} ]} , {'queue.bind', [ {exchange, <<"foo">>} , {queue, <<"hello">>} ]} ]} ]} , {destinations, [ {brokers, ["amqp://hardrock"]} ]} , {queue, <<"hello">>} ]} ]} ]} ].
  • 39. Installation • 1. install RabbitMQ • (install homebrew; brew install rabbitmq; rabbitmq-server [-detached]) • (yum install rabbitmq-server.noarch) • rabbitmqctl or http://server:55672/ • 2. pip install kombu, or pika, or puka, or ...
  • 40. pika "a pure-Python implementation of the AMQP 0-9-1 protocol"
  • 41. Publisher import pika connection = pika.BlockingConnection(pika.ConnectionParameters('server')) channel = connection.channel() channel.queue_declare(queue='hello', durable=True) channel.basic_publish(exchange='', routing_key='hello', body='Hello World!', properties=pika.BasicProperties(delivery_mode=2)) print " [x] Sent 'Hello World!'" connection.close() Publisher Queue
  • 42. Consumer import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() channel.queue_declare(queue='hello', durable=True) print ' [*] Waiting for messages. To exit press CTRL+C' def callback(ch, method, properties, body): print ' [x] Received %r' % (body,) channel.basic_consume(callback, queue='hello') channel.start_consuming() Queue Consumer
  • 43. Remote Consumer Local Publisher
  • 44. Remote queues import pika connection = pika.BlockingConnection(pika.ConnectionParameters('server')) channel = connection.channel() channel.queue_declare(queue='hello', durable=True) print ' [*] Waiting for messages. To exit press CTRL+C' def callback(ch, method, properties, body): print ' [x] Received %r' % (body,) channel.basic_consume(callback, queue='hello') channel.start_consuming() Host 1 Host 2 Publisher Queue Consumer Consumer
  • 45. Remote Consumer Local Consumer Local Publisher
  • 46. Issues • pika's BlockingConnection (my use case is simple enough) hard-codes the socket timeout and fails to cope with latency >1s • Fails to cope at all with packet loss
  • 47. Deleting a Queue import pika connection = pika.BlockingConnection(pika.ConnectionParameters('server')) channel = connection.channel() channel.queue_delete(queue='hello') channel.close() connection.close()
  • 49. Publisher from kombu import BrokerConnection with BrokerConnection('amqp://localhost') as conn: with conn.SimpleQueue('hello') as queue: queue.put('Hello World!') print " [x] Sent 'Hello World!'"
  • 50. Bizarro errors amqplib.client_0_8.exceptions.AMQPChannelException: (406, u"PRECONDITION_FAILED - parameters for queue 'hello' in vhost '/' not equivalent", (50, 10), 'Channel.queue_declare')
  • 51. Publisher from kombu import BrokerConnection with BrokerConnection('amqp://localhost//') as conn: with conn.SimpleQueue('hello', queue_opts=dict(durable=False)) as queue: queue.put('Hello World!') print " [x] Sent 'Hello World!'"
  • 53. Publisher import puka client = puka.Client('amqp://localhost//') client.wait(client.connect()) client.wait(client.queue_declare(queue='hello', durable=True)) promise = client.basic_publish(exchange='', routing_key='hello', body='Hello World!') client.wait(promise) print " [x] Sent 'Hello World!'" client.wait(client.close())
  • 54. Other Plugins • Management (web interface, quite nice) • Federation (Shovel, but with MOAR) • STOMP protocol support
  • 55. STOMP Simple (or Streaming) Text Orientated Messaging Protocol
  • 57. STOMP {rabbitmq_stomp, [ {tcp_listeners, [ {"127.0.0.1", 61613} , {"::1", 61613} ]} , {default_user, [ {login, "guest"} , {passcode, "guest"} ]} ]}
  • 58. stompclient from stompclient import PublishClient client = PublishClient('localhost', 61613) client.connect() client.send('/queue/hello', 'Hello, world!') client.disconnect()
  • 59. stompclient from kombu import BrokerConnection with BrokerConnection('amqp://localhost') as conn: with conn.SimpleQueue('hello') as queue: queue.put('Hello World!') print " [x] Sent 'Hello World!'" from stompclient import PublishClient client = PublishClient('localhost', 61613) client.connect() client.send('/queue/hello', 'Hello, world!') client.disconnect()
  • 60. stompclient from stompclient import PublishClient client = PublishClient('localhost', 61613) client.connect() client.send('/queue/hello', 'Hello, world!') client.disconnect() from stompclient import PublishClient with PublishClient('localhost', 61613) as client: client.send('/queue/hello', 'Hello, world!')
  • 61. Celery "a synchronous or asynchronous task queue/job queue based on distributed message passing"
  • 62. TcpCatcher • TCP, SOCKS, HTTP(S) proxy & monitor • Can introduce latency and transmission errors • Understands HTTP and images • Can debug/interfere/log SSL traffic • Free: www.tcpcatcher.fr

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. Network latency currently means processing slows down.\n
  6. One &quot;facility&quot; is the zipping up of multiple events into a batch and sending the zip across the WAN in one go. This obviously complicates things further and introduces additional latency onto the message transmission.\n
  7. \n
  8. \n
  9. \n
  10. ... and I never actually came back to evaluate it\n
  11. Is message queueing without a broker. Kind of like a glorified socket. Messages are routed in common MQ patterns right down at the network level. If you want store and forward, you&apos;re on your own for the persistence part.\n
  12. \n
  13. AMQP in a nutshell. I might add that amqp.org was no help whatsoever in figuring this out.\n
  14. There&apos;s a bunch of AMQP implementations out there, but in the interests of keeping my own sanity I only looked at the one most popular free implementation. Since they all end up implementing the same thing anyway.\n
  15. \n
  16. \n
  17. Queues are where your messages end up in the broker. They sit there until a client (a.k.a. consumer) connects to the queue and siphons them off. Queues may be configured so messages are discarded if there isn&amp;#x2019;t a consumer ready to accept them. Multiple consumers may connect to a queue - the messages will be passed to each consumer in turn.\n
  18. Exchanges are routers with routing tables that sit in front of queues. They&apos;re declared by consumers, just like queues, except that there&apos;s a default &quot;just pass the message to the queue&quot; exchange for the simple case. Every message has what&amp;#x2019;s known as a &amp;#x201C;routing key&amp;#x201D;, which is simply a string. The exchange has a list of bindings (routes) that say, for example, messages with routing key &amp;#x201C;X&amp;#x201D; go to queue &amp;#x201C;spam&amp;#x201D;.\n
  19. Messages come in to the broker, are routed by exchanges and stored in queues until slurped off by consumers. Within a broker you may have multiple logical systems called virtual hosts. I&apos;m not sure why. There&apos;s a default one and it&apos;s probably all I&apos;ll ever need.\nQueues and exchanges are created programmatically by your producers or consumers - not via a configuration file or command line program - your MQ configuration is in-line with your app code.\n
  20. An interesting aside for performance - exchanges all run in their own processes so adding more exchanges is a way to spread load and increase throughput.\n
  21. &amp;#x201C;routing rules&amp;#x201D; (or bindings) link an exchange to a queue based on a routing key. It is possible for two binding rules to use the same routing key. For example, maybe messages with the routing key &amp;#x201C;audit&amp;#x201D; need to go both to the &amp;#x201C;log-forever&amp;#x201D; queue and the &amp;#x201C;alert-the-big-dude&amp;#x201D; queue. To accomplish this, just create two binding rules (each one linking the exchange to one of the queues) that both trigger on routing key &amp;#x201C;audit&amp;#x201D;. In this case, the exchange duplicates the message and sends it to both queues.\n
  22. There are multiple types of exchanges. They all do routing, but they accept different styles of binding &amp;#x201C;rules&amp;#x201D;. \n
  23. A &quot;direct&quot; exchange only matches if the routing key is &amp;#x201C;dogs&amp;#x201D; or not. The default exchange is a Direct exchange.\n
  24. For example, a &amp;#x201C;topic&amp;#x201D; exchange tries to match a message&amp;#x2019;s routing key against a wildcard pattern like &amp;#x201C;dogs.*&amp;#x201D;.\n
  25. A &quot;fanout&quot; exchange ignores the routing key and distributes the messages to all queues.\n
  26. There&apos;s two levels of persistence in play in RabbitMQ: the structure of the broker and the messages in the broker&apos;s queues.\n\n
  27. You may mark your queues and exchanges as &amp;#x201C;durable&amp;#x201D; so the queue or exchange will be re-created automatically on reboot. It does not mean the messages in the queues will survive the reboot. They won&amp;#x2019;t.\n
  28. When you publish your message to an exchange, you may set a flag called &amp;#x201C;Delivery Mode&amp;#x201D; to the value 2, which means &amp;#x201C;persistent&amp;#x201D;. &amp;#x201C;Delivery Mode&amp;#x201D; usually (depending on your AMQP library) defaults to a value of 1, which means &amp;#x201C;non-persistent&amp;#x201D;.\n
  29. So the steps for persistent messaging are...\nIf you bind a durable queue to a durable exchange, RabbitMQ will automatically preserve the binding. Similarly, if you delete any exchange/queue (durable or not) any bindings that depend on it get deleted automatically.\n
  30. RabbitMQ will not allow you to bind a non-durable exchange to a durable queue, or vice-versa. Both the exchange and the queue must be durable for the binding operation to succeed.\nYou cannot change the creation flags on a queue or exchange after you&amp;#x2019;ve created it. For example, if you create a queue as &amp;#x201C;non-durable&amp;#x201D;, and want to change it to &amp;#x201C;durable&amp;#x201D;, the only way to do this is to destroy the queue and re-create it. It&amp;#x2019;s a good reason to double check your declarations\n
  31. This is my typical setup - I have hosts separated by network (WAN) out of my control. I need all the events generated on the remote hosts to be processed in a timely, reliable manner by the processing server.\n
  32. One solution is to write a forwarding consumer on the remote host - pretty simple code but not very elegant.\n
  33. An alternative setup we could use with the processing server consumer pulling from all the remote host queues. This makes it more configuration work when adding new remote hosts though.\n
  34. Then I discovered the Shovel plugin. I&apos;ve ignored exchanges up until now, but using Shovel allows an exchange on one host to pull messages from a queue and fire them at another queue. It basically runs an erlang client in the remote broker to forward the messages. In theory. In practise...\n
  35. Look hard - it says &quot;Fun&quot; in there. This is NOT FUN. This was bloody hard to figure out. The main problem is that once you decide you&apos;re going to use Shovel, you&apos;re now programming Erlang. See previous statement about fun.\n
  36. Not only am I now learning Erlang but the errors you get back for malformed configuration files (Erlang programs) are really unhelpful. This error basically says &quot;there&apos;s an error somewhere in the 37 lines of your program.&quot;\n
  37. This is my minimum shovel configuration, eventually discovered after much trial-and-error. I shall not share with you the entire volume of bizarre and obscure errors and warnings I waded through to get to this point, nor the number of dead-end alleyways the poor documentation led me down. Unfortunately when you start up the server with this configuration the log file will FILL with warnings about the queue not existing until a client connects and creates the queue.\n
  38. This would probably be simpler if I was familiar with Erlang, but I found the documentation to be basically impenetrable. Also, for some reason I couldn&apos;t declare the queue without declaring an exchange. Which isn&apos;t needed if I don&apos;t declare the queue. There was an awful lot of stumbling around in the dark to get this working, but in the end it does.\n
  39. Default login is guest/guest...\n
  40. It tries to stay fairly independent of the underlying network support library. It uses amqplib underneath by default, which is what most of the libraries do.\n
  41. This code connects to our RabbitMQ server using a blocking connection (send and wait for successful delivery at server before continuing); it declares a durable &quot;helllo&quot; queue and publishes a simple message to the queue. The queue and undelivered messages will be persistent across restarts of RabbitMQ. It&apos;s a slightly bizarrely wordy API. The exchange argument is required, but we use the &quot;no-op&quot; or &quot;default&quot; exchange here. More on them later.\n
  42. This code connects to our RabbitMQ server using a blocking connection (listen and wait for messages); it also declares a &quot;helllo&quot; queue (just in case no publisher is connected) and consumes messages from the queue. You can see that a bunch of the code is the same - connections, channels and queues.\n
  43. Here we see the publisher running on my laptop (local) and the consumer running on the server where the RabbitMQ server is also running. You can see that we can publish into the queue without anything consuming the messages, and we can consume published events immediately. We can also listen as a consumer with no publisher publishing. It&apos;s all quite disconnected.\n
  44. By making one small change to our consumer, we can consume remote queues.\n
  45. Here we set up a second consumer that will consume the remote queue on the server from the local host. Messages published to the queue will be passed to each consumer in turn round-robin style. When a consumer stops consuming the queue will transparently feed all messages to the remaining consumer. And of course this extends to having multiple publishers as well.\n
  46. Can fix the hard-coded socket timeout issue, and a try/except might be able to handle the packet loss.\n
  47. If you set up a queue with the wrong parameters you&apos;ll need to delete it. For some unknown reason the rabbitmq control program doesn&apos;t provide the ability to delete queues, so you need to do it from a client. This code does that.\n
  48. Kombu is a messaging framework for Python. It replaces Carrot.\nThe aim of Kombu is to make messaging in Python as easy as possible by providing an idiomatic high-level interface for the AMQ protocol, and also provide proven and tested solutions to common messaging problems. Its &quot;transports&quot; include AMQP variations and non-AMQP &quot;virtual transports&quot; such as Redis, MongoDB, CouchDB and Beanstalk or &quot;database transports&quot; such as SQLAlchemy and Django ORM.\n
  49. This took me some time to write as the documentation for Kombu is quite limited. Attempting to set things up using channels lead nowhere. I couldn&apos;t find clear documentation on how to create a channel. In the end I found the SimpleQueue which worked after some effort, but I&apos;m still not clear on the details. Then I discovered that the default queue parameters were different (see next slide.)\n
  50. When I was testing early on I wasn&apos;t using durable queues. kombu&apos;s SimpleQueue sets durable to True by default which caused the above bizarro error (which basically says I&apos;m trying to use a queue with different parameters to those it was created with.) This error is not specific to Kombu, but it was unexpected and inexplicable when I first encountered it until I guessed at the durable parameter setting.\n
  51. Took me a while to figure out how to disable durable.\n\nBut again, there&apos;s no channel - it&apos;s really just API noise for simple code like this.\n
  52. The puka module implements a client for AMQP 0-9-1 protocol. It&amp;#x2019;s tuned to work with RabbitMQ broker, but should work fine with other message brokers that support this protocol. It tries to be a nicer API than pika, which is honestly quite appalling.\n
  53. Everything in puka works off the Client which is quite different but pretty convenient. The API is basically the same as pika at the business end. The big difference is in the promises and the ability to wait on the promised action being completed successfully. Puka wants to be asynchronous - the wait() calls effectively force it to be synchronous for simple code like this.\nI needed to patch puka version 0.0.5 as mentioned in issue #15 on their tracker to fix a connection-time issue. Unfortunately even with that fix this was still fragile and inexplicably stopped working at one point. Puka also does away with channels like kombu&apos;s simple case.\n
  54. STOMP is the Simple (or Streaming) Text Orientated Messaging Protocol\n
  55. &quot;STOMP is a very simple and easy to implement protocol, coming from the HTTP school of design; the server side may be hard to implement well, but it is very easy to write a client to get yourself connected. For example you can use Telnet to login to any STOMP broker and interact with it!&quot;\n
  56. The STOMP website kinda mirrors the AMQP website: there&apos;s a specification there but little else. Not so simple. Fortunately there&apos;s a bunch of Python STOMP client libraries.\n
  57. Enabling STOMP was easy enough in the RabbitMQ configuration file - the docs were much clearer and the configuration much simpler than Shovel.\n
  58. So here&apos;s one Python library, stompclient, publishing to my &quot;hello&quot; queue. \n
  59. So... not a whole lot simpler...\n
  60. I made a small change to the stompclient library to allow this usage, which I think is pretty darned simple - I believe it&apos;ll be in the next release. I&apos;m not completely sold on STOMP yet though. I&apos;m not sure it improves things over AMQP enough to switch from just using Kombu.\n
  61. RPC engine. It is focused on real-time operation, but supports scheduling as well. The execution units, called tasks, are executed concurrently on a single or more worker servers. It&apos;s built over kombu and a variety of non-AMQP backends. The RPC nature and backend generality limit the abilities of MQ somewhat, though is nice if you&apos;re just after worker management (which I&apos;m not.)\n
  62. I found this worked sometimes, but not other times. RabbitMQ did NOT like me putting this in the middle of the Shovel setup, but the Python libraries I used were happy to use it as a proxy.\n