{"id":11259,"date":"2016-03-09T12:11:06","date_gmt":"2016-03-09T10:11:06","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=11259"},"modified":"2016-03-02T15:47:27","modified_gmt":"2016-03-02T13:47:27","slug":"rabbitmq-cloud-based-message-oriented-middleware","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/","title":{"rendered":"RabbitMQ : A Cloud based Message Oriented Middleware"},"content":{"rendered":"<p>In this article we will understand RabbitMQ,  a message broker middleware recommeded by <strong><a href=\"http:\/\/www.openstack.org\/\" target=\"_blank\">OpenStack<\/a><\/strong> for cloud deployments. It complies to <strong><a href=\"https:\/\/www.amqp.org\/\" target=\"_blank\">AMQP<\/a><\/strong> standards and developed in Erlang. The code examples are developed using <strong>Python<\/strong> and <strong><a href=\"https:\/\/pika.readthedocs.org\/en\/0.9.14\/\" target=\"_blank\">PIKA<\/a><\/strong> library.<\/p>\n<h2>1. Message Broker<\/h2>\n<p>A message broker is a software component that enables communication across applications in the enterprise application cluster.  It also known as Message Oriented Middleware(MOM) in Service Oriented Architecture (SOA).  The applications in the enterprise cluster use the message broker like a mail-exchange or a post-office to send messages to other applications.<\/p>\n<p>RabbitMQ complies to AMQP standard, which is open standard for business messages between applications and organizations.  It is a binary protocol rather than an interface specification.  AMQP standard enables messaging as a cloud service, advanced publish-subscribe pattern, custom header based rourting and programming language independent.<\/p>\n<h2> 2. RabbitMQ Model<\/h2>\n<p>The RabbitMQ model consits of various components.  They are: <strong>Producer<\/strong> (sender), <strong>Consumer<\/strong> (receiver), <strong>Exchange<\/strong> , <strong>Bindings<\/strong> and <strong>Message queues<\/strong>.  These components work together as explained below:<\/p>\n<ul>\n<li>The producer sends a message to an exchange<\/li>\n<li>Exchange forwards the message to the queues based on the bindings<\/li>\n<li>The bindings are set by queues to attach to an exchange<\/li>\n<li>Consumers (receiver) receives the messages from their respective message queues.<\/li>\n<\/ul>\n<figure id=\"attachment_11263\" aria-describedby=\"caption-attachment-11263\" style=\"width: 705px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/03\/rabbitmq-eco-system2.jpg\" rel=\"attachment wp-att-11263\"><img decoding=\"async\" class=\"wp-image-11263 size-full\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/03\/rabbitmq-eco-system2.jpg\" alt=\"RabbitMQ ECO System\" width=\"705\" height=\"353\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/03\/rabbitmq-eco-system2.jpg 705w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/03\/rabbitmq-eco-system2-300x150.jpg 300w\" sizes=\"(max-width: 705px) 100vw, 705px\" \/><\/a><figcaption id=\"caption-attachment-11263\" class=\"wp-caption-text\">RabbitMQ ECO System<\/figcaption><\/figure>\n<p>The producer and consumer of the messages are external entities. The Exchanges, Queues and Bindings are internal entities of the message broker.<\/p>\n<h3>2.1 Exchanges<\/h3>\n<p>Exchanges are core of RabbitMQ.  The producer sends messages to exchanges to forward it to the right consumer.  Exchanges make forwarding decision based on exchange type, routing_key in the message, custome header fields in the message, and the routing_key registered by the queue with the exchange.<\/p>\n<p>Exchanges can be configured durable, so that they will survive restarts of the RabbitMQ server. Exchanges can be \u201cinternal\u201d to server, so that it can be published by other exchanges inside the server.   The exchanges can be configured to auto-delete, while no more queues are bound to it.<\/p>\n<h3>2.2 Queues<\/h3>\n<p>Queues are used to forward the messages to target consumers and ensures orderly message delivery. The consumer bind itself to a queue with a callback function, so that consumer will be notified on receiving a message.<\/p>\n<p>Queues can be configured durable, so that they will survive restarts of the RabbitMQ server. It can also be configured \u201cexclusive\u201d to a connection, once the connection is closed the queue will be deleted. Auto-delete queues are deleted when no consumer is subscribed to the queue.<\/p>\n<h3>2.3 Bindings<\/h3>\n<p>Bindings are used by the exchanges to make the routing decision for a message. Basically bindings connects the exchanges with the queues and it uses exchange-type, routing-key set by the queue, custom message headers and routing-key present in the message sent by the producer.  If there are not enough bindings to make a forwarding decision for a message, the message can be dropped or sent back to the producer, based on the properties set in the message.<\/p>\n<h2>3. Producer and Consumer<\/h2>\n<p>In a typical banking system, when a customer withdraws money from the ATM or swipes his credit card at a shop, the customer is notified with a SMS or an email to prevent frauds.  In this use case, the core banking system will send a message to messaging sub-systems and continue process other customer requests.  The messaging sub-systems listening on the queues will be notified and they take appropriate actions based on subscriber preferences.  In this example, the core banking system is the producer of the messages and messaging sub-system are consumer of the messages.<\/p>\n<h3>3.1 Producer<\/h3>\n<p>As per RabbitMQ design, the producer sends the message to an exchange.  The behaviour of the exchange defined by the exchange type, route_key &amp; bindings by the message queues.  Let us see how to create a producer using Python pika library.  If you do not have RabbitMQ setup, please refer the <strong>Appendix-A<\/strong> section to install and configure RabbitMQ.<\/p>\n<pre class=\"brush:python\">import pika \r\n\r\n\"\"\" Establish connection and declare the exchange\"\"\"\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))\r\nchannel = connection.channel()\r\nchannel.exchange_declare(exchange=\"SMS-Exchange\",exchange_type=\"direct\")\r\n\r\n\"\"\" Publish a Message on the Channel \"\"\"\r\nMsg = \"Balance as of today is 200.00$\"\r\nchannel.basic_publish(exchange = \"SMS-Exchange\",routing_key=\"Sms-Alert\",body=Msg)\r\n\r\n\"\"\"Close the communication channel \"\"\"\r\nconnection.close()<\/pre>\n<p>In the above code segment, first we establish connection to server, where RabbitMQ is hosted.  RabbitMQ allows to establish multiple channel within the existing connection and all the communications are operations are tied with that channel.  The 3rd line, we create an exchange and named it \u201cSMS-Exchange\u201d and its type is \u201cdirect\u201d.  In case if the exchange is already created, this statement will not create an error it simply returns it unless there is no conflict in the exchange type.<\/p>\n<p>The function \u201cchannel.basic_publish\u201d is used to send a message to the exchange.  The producer has to mention that name of exchange and routing_key along with the actual message.  In \u201cdirect\u201d exchange the \u201crouting_key\u201d will be used to make message forwarding decision.  Finally close the connection, if not needed any more.<\/p>\n<h3>3.2 Consumer<\/h3>\n<p>As per RabbitMQ design, the consumer is the target application where the messages are intended.  The consumer must register itself to a queue and bind it with the exchange.  If more than one consumers registers to a queue, then RabbitMQ sends the messages to consumers in round-robin fashion.<\/p>\n<pre class=\"brush:python\">import pika\r\n\r\n\"\"\" define a callback function to receive the message \"\"\"\r\ndef callback(channel,method,properties,body):\r\n    print \"[X] Received Message \",body\r\n\r\n\"\"\" Establish connection \"\"\"\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')\r\nchannel = connection.channel()\r\n\r\n\"\"\" Declare the queue &amp; bind to the exchange with routing key \"\"\"\r\nchannel.queue_declare(queue=\"SMS-Queue\")\r\nchannel.queue_bind(exchange=\"SMS-Exchange\",queue=\"SMS-Queue\",routing_key=\"SMS-Alert\")\r\n\r\n\"\"\" register the call back function \"\"\"\r\nchannel.basic_consume(callback,queue=\"SMS-Queue\",no_ack=True)\r\n\r\n\"\"\" listen to the queue \"\"\"\r\nchannel.start_consuming()<\/pre>\n<p>The connection establishment is exactly same for both producer and consumer.  But the consumer has to declare a queue and bind the queue with the exchange along with routing_key.  In the above code, the \u201cSMS-Queue\u201d is created and bound with \u201cSMS-Exchange\u201d with routing_key \u201cSMS-Alert\u201d.  This instructs the SMS-Exchange to forward the message with routing_key \u201cSMS-Alert\u201d to \u201cSMS-Queue\u201d.<\/p>\n<p>The callback function registered with the queue will be called once message is received on the queue.  The list statement \u201cchannel.start_consuming()\u201d is a blocking call, where the consumer awaits for any messages on the registered queue.<\/p>\n<h3>3.3 Remote Connection<\/h3>\n<p>In the above examples we have connected to RabbitMQ server which is present in the localhost.  Lets see the code snippet, how to connect to a remote RabbitMQ server:<\/p>\n<pre class=\"brush:python\">import pika\r\ncredits = pika.PlainCredentials('scott','tiger')\r\nparams = pika.ConnectionParameters('10.0.0.1',5672,'\/',credits)\r\nconnection = pika.BlockingConnection(parameters=params)<\/pre>\n<p>The above code, first creates a credits object by setting up the user credentials.  Then we create a parameters object by setting up the IP address, port number, virtual host path and credential object.  This parameter is simply passed to BlockingConnection method to establish connection with the given parameters.  Once you establish a connection, the rest of code is exactly same for creating a producer and consumer.<\/p>\n<p>In this exercise we have discussed developing producer and consumer using blocking connection.  RabbitMQ also supports asynchronous connections.  Please find the examples at <a href=\"http:\/\/pika.readthedocs.org\/en\/latest\/examples\/asynchronous_publisher_example.html\" target=\"_blank\">http:\/\/pika.readthedocs.org\/en\/latest\/examples\/asynchronous_publisher_example.html<\/a> .<\/p>\n<h2>4. Exchange Types<\/h2>\n<p>In this section we will learn how to develop various types of exchanges.<\/p>\n<h3>4.1 Direct Exchange<\/h3>\n<p>A direct exchange delivers messages to queues based on the message routing key. A queue binds to the exchange with a routing key. When a new message with that routing key arrives at the direct exchange, that message is routed to that queue. Direct exchanges are used to distribute tasks between multiple workers in a round robin manner. RabbitMQ load balances the consumers, when multiple consumers listens on the same queue. A direct exchange is ideal for the unicast routing of message.<\/p>\n<p><strong>Producer:<\/strong> The below code segment creates an exchange named \u201cDirect-X\u201d and set the exchange type to \u201cdirect\u201d.   The postMsg method sends the message to this exchange with routing_key set to \u201cKey1\u201d<\/p>\n<pre class=\"brush:python\">import pika \r\n\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))\r\nchannel = connection.channel()\r\n\r\n\"\"\" Declare a exchange with type as direct \"\"\"\r\nchannel.exchange_declare(exchange=\"Direct-X\",exchange_type=\"direct\")\r\n\r\n\"\"\" Publish a Message on the Channel \"\"\"\r\nMsg = raw_input(\"Please enter the message :\")\r\nchannel.basic_publish(exchange = \"Direct-X\",routing_key=\"Key1\",body=Msg)\r\n\r\n\"\"\"Close the communication channel \"\"\"\r\nconnection.close()<\/pre>\n<p><strong>Consumer:<\/strong><\/p>\n<p>The below code snippet creates Queue named \u201cDirect-Q1\u201d and registers it with the exchange \u201cDirect-X\u201d for the messages with the routing_key as \u201cKey1\u201d.<\/p>\n<pre class=\"brush:python\">import pika\r\n\r\n\"\"\" define a callback function to receive the message \"\"\"\r\ndef callback(channel,method,properties,body):\r\n    print \"[X] Received Message \",body\r\n\r\n\"\"\" Establish connection \"\"\"\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')\r\nchannel = connection.channel()\r\n\r\n\"\"\" Declare the queue &amp; bind to the exchange with routing key \"\"\"\r\nchannel.queue_declare(queue=\"Direct-Q\")\r\nchannel.queue_bind(exchange=\"Direct-X\",queue=\"Direct-Q\",routing_key=\"Key1\")\r\n\"\"\" register the call back function \"\"\"\r\nchannel.basic_consume(callback,queue=\"Direct-Q\",no_ack=True)\r\n\r\n\"\"\" listen to the queue \"\"\"\r\nchannel.start_consuming()<\/pre>\n<p>Note: If more than one consumers listens to the same queue, RabbitMQ  load balances the messages across the consumers in round-robin fashion.<\/p>\n<h3>4.2 Fanout Exchange<\/h3>\n<p>A fanout exchange routes messages to all the queues that are bounded irrespective of the routing key. It is most suitable for broadcast.<\/p>\n<p><strong>Producer: <\/strong><br \/>\nCreate a producer which sent message to the exchange \u201cFanout-X\u201d.<\/p>\n<pre class=\"brush:python\">import pika \r\n\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))\r\nchannel = connection.channel()\r\n\r\n\"\"\" Declare a exchange with type as direct \"\"\"\r\nchannel.exchange_declare(exchange=\"Fanout-X\",exchange_type=\"fanout\")\r\n\r\n\"\"\" Publish a Message on the Channel \"\"\"\r\nMsg = raw_input(\"Please enter the message :\")\r\nchannel.basic_publish(exchange = \"Fanout-X\",routing_key=\"Key1\",body=Msg)\r\n\r\n\"\"\"Close the communication channel \"\"\"\r\nconnection.close()<\/pre>\n<p><strong>Consumer 1:<\/strong><\/p>\n<p>Creates a queue \u201cFaount-Q1\u201d and binds to exchange \u201cFanout-X\u201d, which is of fanout exchange type. Even though the consumer registers a routing_key, it will not have any effect on exchange\u2019s forwarding decision, because it is a fanout exchange.<\/p>\n<pre class=\"brush:python\">import pika\r\n\r\n\"\"\" define a callback function to receive the message \"\"\"\r\ndef callback(channel,method,properties,body):\r\n    print \"[X] Received Message \",body\r\n\r\n\"\"\" Establish connection \"\"\"\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')\r\nchannel = connection.channel()\r\n\r\n\"\"\" Declare the queue &amp; bind to the exchange with routing key \"\"\"\r\nchannel.queue_declare(queue=\"Fanout-Q1\")\r\nchannel.queue_bind(exchange=\"Direct-X\",queue=\"Fanout-Q1\",routing_key=\"Key1\")\r\n\"\"\" register the call back function \"\"\"\r\nchannel.basic_consume(callback,queue=\"Fanout-Q1\",no_ack=True)\r\n\r\n\"\"\" listen to the queue \"\"\"\r\nchannel.start_consuming()<\/pre>\n<p><strong>Consumer 2:<\/strong> Creates a another queue \u201cFanout-Q2\u201d and binds it to the same exchange \u201cFanout-X\u201d<\/p>\n<pre class=\"brush:python\">import pika\r\n\r\n\"\"\" define a callback function to receive the message \"\"\"\r\ndef callback(channel,method,properties,body):\r\n    print \"[X] Received Message \",body\r\n\r\n\"\"\" Establish connection \"\"\"\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')\r\nchannel = connection.channel()\r\n\r\n\"\"\" Declare the queue &amp; bind to the exchange with routing key \"\"\"\r\nchannel.queue_declare(queue=\"Fanout-Q2\")\r\nchannel.queue_bind(exchange=\"Fanout-X\",queue=\"Fanout-Q2\",routing_key=\"Key1\")\r\n\"\"\" register the call back function \"\"\"\r\nchannel.basic_consume(callback,queue=\"Fanout-Q2\",no_ack=True)\r\n\r\n\"\"\" listen to the queue \"\"\"\r\nchannel.start_consuming()<\/pre>\n<p>Now you will see that the message sent by the publisher will be received by both consumers.<\/p>\n<h3>4.3 Topic Exchange<\/h3>\n<p>Topic exchange route messages to one or more queues based on the message routing key and key-pattern used to bind a queue to an exchange. This is exchange is used to implement <strong>publish\/subscriber<\/strong> pattern. Topic exchange is suitable for multicast.<\/p>\n<p><strong>Producer <\/strong>creates an exchange named \u201cTopic-X\u201d of type \u201ctopic\u201d and sends various messages with different key values.<\/p>\n<pre class=\"brush:python\">import pika \r\n\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))\r\nchannel = connection.channel()\r\n\r\n\"\"\" Declare a exchange with type as direct \"\"\"\r\nchannel.exchange_declare(exchange=\"Topic-X\",exchange_type=\"topic\")\r\n\r\n\"\"\" Publish a Message on the Channel \"\"\"\r\nMsg = raw_input(\"Please enter the message :\")\r\nchannel.basic_publish(exchange = \"Topic-X\",routing_key=\"in.sales.put\",body=Msg)\r\nchannel.basic_publish(exchange = \"Topic-X\",routing_key=\"in.sales.post\",body=Msg)\r\nchannel.basic_publish(exchange = \"Topic-X\",routing_key=\"in.sales.delete\",body=Msg)\r\nchannel.basic_publish(exchange = \"Topic-X\",routing_key=\"in.rnd.put\",body=Msg)\r\nchannel.basic_publish(exchange = \"Topic-X\",routing_key=\"in.rnd.post\",body=Msg)\r\nchannel.basic_publish(exchange = \"Topic-X\",routing_key=\"in.rnd.delete\",body=Msg)\r\n\"\"\"Close the communication channel \"\"\" \r\nconnection.close()<\/pre>\n<p><strong>Consumer 1:<\/strong> Creates a queue named \u201cTopic-Q1\u201d and binds with exchange \u201cTopic-X\u201d for all the \u201cpost\u201d messages.<\/p>\n<pre class=\"brush:python\">import pika\r\n\r\n\"\"\" define a callback function to receive the message \"\"\"\r\ndef callback(channel,method,properties,body):\r\n    print \"[X] Received Message \",body\r\n\r\n\"\"\" Establish connection \"\"\"\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')\r\nchannel = connection.channel()\r\n\r\n\"\"\" Declare the queue &amp; bind to the exchange with routing key \"\"\"\r\nchannel.queue_declare(queue=\"Topic-Q1\")\r\nchannel.queue_bind(exchange=\"Topic-X\",queue=\"Topic-Q1\",routing_key=\"*.*.post\")\r\n\"\"\" register the call back function \"\"\"\r\nchannel.basic_consume(callback,queue=\"Topic-Q1\",no_ack=True)\r\n\r\n\"\"\" listen to the queue \"\"\"\r\nchannel.start_consuming()<\/pre>\n<p><strong>Consumer 2:<\/strong> Creates another queue named \u201cTopic-Q2\u201d and binds with the same exchange \u201cTopic-X\u201d for all messages coming from \u201crnd\u201d.<\/p>\n<pre class=\"brush:python\">import pika\r\n\r\n\"\"\" define a callback function to receive the message \"\"\"\r\ndef callback(channel,method,properties,body):\r\n    print \"[X] Received Message \",body\r\n\r\n\"\"\" Establish connection \"\"\"\r\nconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')\r\nchannel = connection.channel()\r\n\r\n\"\"\" Declare the queue &amp; bind to the exchange with routing key \"\"\"\r\nchannel.queue_declare(queue=\"Topic-Q2\")\r\nchannel.queue_bind(exchange=\"Topic-X\",queue=\"Topic-Q2\",routing_key=\"in.rnd.*\")\r\n\"\"\" register the call back function \"\"\"\r\nchannel.basic_consume(callback,queue=\"Topic-Q2\",no_ack=True)\r\n\r\n\"\"\" listen to the queue \"\"\"\r\nchannel.start_consuming()<\/pre>\n<h3>4.4 Headers Exchange<\/h3>\n<p>Header exchanges route message based on attributes in message header and it ignores the routing-key. If a message header attributes matches with the queue binding parameters, then the message is forwarded to those queues.<\/p>\n<p><strong>Producer<\/strong> can set key, value pair (dictionary) in the header of the message sent.<\/p>\n<pre class=\"brush:python\">import pika\r\n\r\n\"\"\" A dictionary to store the customer headers \"\"\"\r\nheader={}\r\nheader['Source']='Core-Banking'\r\nheader['Destination']='Message-System'\r\n\r\n\"\"\" Establish Blocking Connection with RabbitMQ Server \"\"\"\r\nconn = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))\r\nchan = conn.channel()\r\n\r\n\"\"\" Declare an exchange and set type as headers \"\"\"\r\nchan.exchange_declare(exchange=\"Header-X\",exchange_type=\"headers\")\r\n\r\n\"\"\"Set the headers using BasicProperties api \"\"\"\r\nprop = pika.BasicProperties(headers=header)\r\n\r\n\"\"\"Publish the message to the exchange \"\"\"\r\nmsg = \"Hello Message-System, I am Core-Banking\"\r\nchan.basic_publish(exchange='Header-X',routing_key=\"Key1\",body=msg,properties=prop)\r\nchan.close()<\/pre>\n<p>The above producer, creates an exchange named \u201cHeader-X\u201d and set the type to \u201cheaders\u201d. Then it sends a message with header key set to \u201cSource\u201d and the respective value set to \u201cCore-Banking\u201d. Basically the message header is bundled with the originator of the message, in this example it is \u201cCore-Banking\u201d.<\/p>\n<p>The below <strong>Consumer<\/strong> creates a queue named \u201c<em>Header-Q1<\/em>\u201d and binds it with \u201c<em>Header-X<\/em>\u201d along with header information it is interested.  If you refer the post Method, it<\/p>\n<pre class=\"brush:python\">que='Header-Q'\r\nexg = 'Header-X'\r\nkey='Source'\r\nval='Core-Banking'\r\n\r\n\"\"\" Declare a call back function to receive the message \"\"\"\r\ndef callback(ch,method,properties,body):\r\n print \"[X] Received Msg\",body\r\n\r\n\"\"\" Establish blocking connection to the server \"\"\"\r\nconn = pika.BlockingConnection( pika.ConnectionParameters(host='localhost'))\r\nchan = conn.channel()\r\n\r\n\"\"\" Declare a Queue \"\"\"\r\nchan.queue_declare(queue=que)\r\n\r\n\"\"\"Bind the queue to exchange and set arguments to match any of the given header \"\"\"\r\nchan.queue_bind(exchange=exg,queue=que, arguments={key:val,'x-match':'any'})\r\n\r\nprint '[*] Wait for messages. To exit press CTRL+C'\r\n\r\n\"\"\" Link the callback function to the queue \"\"\"\r\nchan.basic_consume(callback,queue=que,no_ack=True)\r\n\r\n\"\"\"Wait for the messages to arrive \"\"\"\r\nchan.start_consuming()<\/pre>\n<p>Note that the queue_bind statement takes additional argument, named \u201carguments\u201d which takes the key-value pair. If there are more than one key-value pair present, x-match:any will ensure that even if a single entry matches the message will be delivered to this queue.<\/p>\n<h2>5. Summary<\/h2>\n<p>We have seen how RabbitMQ works, understand various componenets and messaging models.  RabbitMQ  supports high available clustering environments, which will ensure zero down time, higher throughput and increased capacity, which makes it suitable for cloud based installations.<\/p>\n<h2>6. References<\/h2>\n<p>1. Message Broker \u2013 <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ff648849.aspx\" target=\"_blank\">https:\/\/msdn.microsoft.com\/en-us\/library\/ff648849.aspx<\/a><br \/>\n2. AMQP \u2013 <a href=\"https:\/\/www.rabbitmq.com\/tutorials\/amqp-concepts.html\" target=\"_blank\">https:\/\/www.rabbitmq.com\/tutorials\/amqp-concepts.html<\/a><br \/>\n3. RabbitMQCtl Command Reference : <a href=\"https:\/\/www.rabbitmq.com\/man\/rabbitmqctl.1.man.html\" target=\"_blank\">https:\/\/www.rabbitmq.com\/man\/rabbitmqctl.1.man.html<\/a><br \/>\n4. PIKA Documentation \u2013 <a href=\"http:\/\/pika.readthedocs.org\/en\/latest\/modules\/index.html\" target=\"_blank\">http:\/\/pika.readthedocs.org\/en\/latest\/modules\/index.html<\/a><br \/>\n5. AMQP Standards \u2013 <a href=\"https:\/\/www.amqp.org\/\" target=\"_blank\">https:\/\/www.amqp.org\/<\/a><\/p>\n<h2>Appendix \u2013 A<\/h2>\n<h2>A. Installation &amp; Configuration<\/h2>\n<p>The rabbitMQ infrastrcture is installed in CentOS6.5<\/p>\n<h3>A.1 Installation<\/h3>\n<p>Please install RabbitMQ, Erlang ( RabbitMQ runs on Erlang), Python &amp; Pika.<\/p>\n<ul>\n<li>To install <strong>RabbitMQ<\/strong>  <strong>(v3.5.3)<\/strong> refer <a href=\"https:\/\/www.rabbitmq.com\/download.html\" target=\"_blank\">https:\/\/www.rabbitmq.com\/download.html<\/a> &amp; follow the instructions based on your target operating system.  I have installed rabbitMQ on CentOS machine.<\/li>\n<li><strong>Erlang<\/strong> <em>(v18.0)<\/em>can be installed from  <a href=\"http:\/\/www.erlang.org\/doc\/installation_guide\/INSTALL.html\" target=\"_blank\">http:\/\/www.erlang.org\/doc\/installation_guide\/INSTALL.html<\/a><\/li>\n<li><strong>Python 2.7.10<\/strong> is available <a href=\"https:\/\/www.python.org\/downloads\/\" target=\"_blank\">https:\/\/www.python.org\/downloads\/<\/a>.  Please install version 2.7.10, since pika support is not yet available for 3.x and it is currently under development.<\/li>\n<li><strong>Pika<\/strong> <em>(v0.9.13)<\/em> can be used using Python pip.\n<ul>\n<li>\n<pre class=\"brush:python\">  pip install pika<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>A.2 Install RabbitMQ Management Plugin<\/h3>\n<p>RabbitMQ comes with a web based management console.  The software is bundled along with the RabbitMQ installation software we have installed.  To enable management console, execute the below command in your linux machine:<\/p>\n<pre class=\"brush:python\">rabbitmq-plugins enable rabbitmq_management<\/pre>\n<p>RabbitMQ management console uses the port 15672. So, this port must be opened.  Please refer <a href=\"https:\/\/www.rabbitmq.com\/management.html\" target=\"_blank\">https:\/\/www.rabbitmq.com\/management.html<\/a> for further information on Management Plugin.<\/p>\n<p>After enabling the management plug-in, you can open the <em><a href=\"http:\/\/ipaddress:15672\/\" rel=\"nofollow\">http:\/\/ipaddress:15672\/<\/a><\/em> in your browser to see the Web Management Interface of RabbitMQ.<\/p>\n<h3>A.3 Configuring RabbitMQ (vhost\/user\/privileges)<\/h3>\n<p>Once you have installed RabbitMQ it is ready for production.  But we have to make few mandatory configurations in order to allow remote clients, because the default configuration and user privilages will not allow the remove clients to access the server.<\/p>\n<p>The idea here is to create a virtual environment with the RabbitMQ server and provide access to a user, where he can create a Message Queue, Exchange, Read  and Write into those resources.  So the users are restricted to a virtual environment and resources are contained within the environment.<\/p>\n<h4>A.3.1 Create a Virtual Host<\/h4>\n<pre class=\"brush:python\">rabbitmqctl add_vhost &lt;virtual_host_name&gt;<\/pre>\n<p>Note : RabbitMQ will have a default virtual host named \u201c\/\u201d.<\/p>\n<h4>A.3.2 Create a New User with password<\/h4>\n<pre class=\"brush:python\">rabbitmqctl add_user &lt;username&gt; &lt;password&gt;<\/pre>\n<pre class=\"brush:python\">Eg. rabbitmqctl add_user scott tiger<\/pre>\n<p>Note: RabbitMQ will have a default user named \u201cguest\u201d, but it cannot used for remote access by external clients. But it allows when the server is acessed locally.<\/p>\n<h4>A.3.3 Assign permissions to the user to access a vhost<\/h4>\n<pre class=\"brush:python\">set_permissions [-p vhostpath] {user} {conf} {write} {read}<\/pre>\n<pre class=\"brush:python\">Eg: set_permission -p \"\/\" \"scott\" \".*\"  \".*\" \".*\"<\/pre>\n<p>Refer <a href=\"https:\/\/www.rabbitmq.com\/access-control.html\" target=\"_blank\">https:\/\/www.rabbitmq.com\/access-control.html<\/a> for more information.<\/p>\n<h3>A.4 Firewall Settings<\/h3>\n<p>We have to open the necessary ports of the Linux Firewall in order to allow remote clients.  Perform the following operations on the IP table to open the ports 5672 &amp; 15672.<\/p>\n<pre class=\"brush:python\">sudo iptables -I INPUT -p tcp --dport 5672 --syn -j ACCEPT\r\nsudo iptables -I INPUT -p tcp --dport 15672 --syn -j ACCEPT<\/pre>\n<p>To make the changes permenent, make the configuration changes in the file <em>\/etc\/sysconfig\/iptables<\/em> and restart the iptables servers:<\/p>\n<pre class=\"brush:python\">sudo service iptables restart<\/pre>\n<h3>A.5 Linux commands to manage the RabbitMQ server<\/h3>\n<pre class=\"brush:python\">service rabbitmq-server start\r\nservice rabbitmq-server stop\r\nservice rabbitmq-server status\r\nservice rabbitmq-server restart<\/pre>\n<p>To start rabbitMQ as a daemon:<\/p>\n<p><em>chkconfig rabbitmq-server on<\/em><\/p>\n<h3>A.6 RabbitMQ Commands<\/h3>\n<ul>\n<li>List all exchanges           <em>rabbitmqctl list_exchanges<\/em><\/li>\n<li>List all queues                 <em>rabbitmqctl list_queues<\/em><\/li>\n<li>List all bindings              <em>rabbitmqctl list_bindings<\/em><\/li>\n<li>List consumers               <em>rabbitmqctl list_consumers<\/em><\/li>\n<li>List connections             <em>rabbitmqctl list_connections<\/em><\/li>\n<\/ul>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/techietweak.wordpress.com\/2015\/08\/14\/rabbitmq-a-cloud-based-message-oriented-middleware\/\">RabbitMQ : A Cloud based Message Oriented Middleware<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a> Saravanan Subramanian at the <a href=\"http:\/\/techietweak.wordpress.com\/\">Saravanan Subramanian Tech Notes<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this article we will understand RabbitMQ, a message broker middleware recommeded by OpenStack for cloud deployments. It complies to AMQP standards and developed in Erlang. The code examples are developed using Python and PIKA library. 1. Message Broker A message broker is a software component that enables communication across applications in the enterprise application &hellip;<\/p>\n","protected":false},"author":143,"featured_media":927,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[341],"class_list":["post-11259","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development","tag-rabbitmq"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>RabbitMQ : A Cloud based Message Oriented Middleware - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"In this article we will understand RabbitMQ, a message broker middleware recommeded by OpenStack for cloud deployments. It complies to AMQP standards and\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"RabbitMQ : A Cloud based Message Oriented Middleware - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"In this article we will understand RabbitMQ, a message broker middleware recommeded by OpenStack for cloud deployments. It complies to AMQP standards and\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/saravanan.subramanian.31\" \/>\n<meta property=\"article:published_time\" content=\"2016-03-09T10:11:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Saravanan Subramanian\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@tosarvan\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Saravanan Subramanian\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/\"},\"author\":{\"name\":\"Saravanan Subramanian\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/56779276fba995e603f50ea6f18bdd8a\"},\"headline\":\"RabbitMQ : A Cloud based Message Oriented Middleware\",\"datePublished\":\"2016-03-09T10:11:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/\"},\"wordCount\":2183,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"keywords\":[\"RabbitMQ\"],\"articleSection\":[\"Web Dev\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/\",\"name\":\"RabbitMQ : A Cloud based Message Oriented Middleware - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"datePublished\":\"2016-03-09T10:11:06+00:00\",\"description\":\"In this article we will understand RabbitMQ, a message broker middleware recommeded by OpenStack for cloud deployments. It complies to AMQP standards and\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Dev\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/web-development\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"RabbitMQ : A Cloud based Message Oriented Middleware\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/56779276fba995e603f50ea6f18bdd8a\",\"name\":\"Saravanan Subramanian\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d5b5095370698b8a3f2dfd7ade5444c1b7ec66ed3f549b8a9dcda5580c3a80dd?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d5b5095370698b8a3f2dfd7ade5444c1b7ec66ed3f549b8a9dcda5580c3a80dd?s=96&d=mm&r=g\",\"caption\":\"Saravanan Subramanian\"},\"description\":\"Saravanan Subramanian is a System Architect cum Agile Product Owner for developing cloud based applications for service provider back office enterprise applications using open source technologies. He is passionate about Cloud Technology and Big Data Analytics.\",\"sameAs\":[\"http:\/\/techietweak.wordpress.com\/\",\"https:\/\/www.facebook.com\/saravanan.subramanian.31\",\"https:\/\/in.linkedin.com\/in\/tosarvan\",\"https:\/\/x.com\/tosarvan\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/saravanan-subramanian\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"RabbitMQ : A Cloud based Message Oriented Middleware - Web Code Geeks - 2026","description":"In this article we will understand RabbitMQ, a message broker middleware recommeded by OpenStack for cloud deployments. It complies to AMQP standards and","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/","og_locale":"en_US","og_type":"article","og_title":"RabbitMQ : A Cloud based Message Oriented Middleware - Web Code Geeks - 2026","og_description":"In this article we will understand RabbitMQ, a message broker middleware recommeded by OpenStack for cloud deployments. It complies to AMQP standards and","og_url":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_author":"https:\/\/www.facebook.com\/saravanan.subramanian.31","article_published_time":"2016-03-09T10:11:06+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","type":"image\/jpeg"}],"author":"Saravanan Subramanian","twitter_card":"summary_large_image","twitter_creator":"@tosarvan","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Saravanan Subramanian","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/"},"author":{"name":"Saravanan Subramanian","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/56779276fba995e603f50ea6f18bdd8a"},"headline":"RabbitMQ : A Cloud based Message Oriented Middleware","datePublished":"2016-03-09T10:11:06+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/"},"wordCount":2183,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","keywords":["RabbitMQ"],"articleSection":["Web Dev"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/","url":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/","name":"RabbitMQ : A Cloud based Message Oriented Middleware - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","datePublished":"2016-03-09T10:11:06+00:00","description":"In this article we will understand RabbitMQ, a message broker middleware recommeded by OpenStack for cloud deployments. It complies to AMQP standards and","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/web-development\/rabbitmq-cloud-based-message-oriented-middleware\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Web Dev","item":"https:\/\/www.webcodegeeks.com\/category\/web-development\/"},{"@type":"ListItem","position":3,"name":"RabbitMQ : A Cloud based Message Oriented Middleware"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/56779276fba995e603f50ea6f18bdd8a","name":"Saravanan Subramanian","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d5b5095370698b8a3f2dfd7ade5444c1b7ec66ed3f549b8a9dcda5580c3a80dd?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d5b5095370698b8a3f2dfd7ade5444c1b7ec66ed3f549b8a9dcda5580c3a80dd?s=96&d=mm&r=g","caption":"Saravanan Subramanian"},"description":"Saravanan Subramanian is a System Architect cum Agile Product Owner for developing cloud based applications for service provider back office enterprise applications using open source technologies. He is passionate about Cloud Technology and Big Data Analytics.","sameAs":["http:\/\/techietweak.wordpress.com\/","https:\/\/www.facebook.com\/saravanan.subramanian.31","https:\/\/in.linkedin.com\/in\/tosarvan","https:\/\/x.com\/tosarvan"],"url":"https:\/\/www.webcodegeeks.com\/author\/saravanan-subramanian\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/11259","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/143"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=11259"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/11259\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/927"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=11259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=11259"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=11259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}