@@ -14,14 +14,16 @@ Learning RabbitMQ, part 1 ("Hello world!")
14
14
15
15
Throughout this tutorial, we'll teach you the basic concepts required for
16
16
creating RabbitMQ applications. The tutorial will be illustrated with
17
- code snippets written in [ Python] ( http://www.python.org/ ) . But don't worry if
18
- you don't know this language - the core ideas are the same for other languages.
17
+ code snippets written in [ Python] ( http://www.python.org/ ) and executed on Linux.
18
+ But don't worry if you don't know this language - the core ideas are the same
19
+ for other languages.
20
+
19
21
20
22
This tutorial consists of three parts:
21
23
22
24
* First we're going to write the simplest possible "Hello World" example.
23
- * Next we'll try to use Rabbit as a simple "Work queue" server.
24
- * Finally, we'll discuss the "Publish-subscribe" pattern .
25
+ * Next we'll try to use Rabbit as [ a simple "Work queue" server] ( http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/python/tutorial-two.md ) .
26
+ * Finally, we'll discuss how to [ broadcast a message ] ( http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/python/tutorial-three.md ) .
25
27
26
28
You need to have RabbitMQ server installed to go through this tutorial.
27
29
If you haven't installed it yet you can follow the
@@ -46,15 +48,16 @@ If you have installed RabbitMQ you should see something like:
46
48
> #### Where to get help
47
49
>
48
50
> If you're having trouble going through this tutorial you can post a message to
49
- > [ rabbitmq-discuss mailing list] ( https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss ) .
51
+ > [ rabbitmq-discuss mailing list] ( https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss )
52
+ > or join the [ #rabbitmq] ( irc://irc.freenode.net/rabbitmq ) irc channel.
50
53
51
54
52
55
Introduction
53
56
------------
54
57
55
58
RabbitMQ is a message broker. The principle idea is pretty simple: it accepts
56
59
and forwards messages. You can think about it as a post office: when you send
57
- mail to the post box and you're pretty sure that mr postman will eventually
60
+ mail to the post box and you're pretty sure that Mr. Postman will eventually
58
61
deliver the mail to your recipient. Using this metaphor RabbitMQ is a post box,
59
62
post office and a postman.
60
63
@@ -65,7 +68,7 @@ blobs of data - _messages_.
65
68
RabbitMQ uses a weird jargon, but it's simple once you'll get it. For example:
66
69
67
70
* _ Producing_ means nothing more than sending. A program that sends messages
68
- is a _ producer_ .
71
+ is a _ producer_ . We'll draw it like that, with "P":
69
72
70
73
71
74
<center ><div class =" dot_bitmap " >
@@ -79,16 +82,17 @@ RabbitMQ uses a weird jargon, but it's simple once you'll get it. For example:
79
82
is not bound by any limits, it can store how many messages you
80
83
like - it's essentially an infinite buffer. Many _ producers_ can send
81
84
messages that go to the one queue, many _ consumers_ can try to
82
- receive data from one _ queue_ .
85
+ receive data from one _ queue_ . Queue'll be drawn as like that, with
86
+ its name above it:
83
87
84
88
85
89
<center ><div class =" dot_bitmap " >
86
- <img src =" http://github.com/rabbitmq/rabbitmq-tutorials/raw/master/_img/9bdb70c65ab8b2aa1f6b0b85c2931a54 .png " alt =" Dot graph " width =" 76 " height =" 29 " />
90
+ <img src =" http://github.com/rabbitmq/rabbitmq-tutorials/raw/master/_img/3c4ce95dcbad1b510cfd4c2ee86d8a35 .png " alt =" Dot graph " width =" 116 " height =" 87 " />
87
91
</div ></center >
88
92
89
93
90
- * _ Consuming_ has a simmilar meaning to receiving. _ Consumer_ is a program
91
- that mostly waits to receive messages.
94
+ * _ Consuming_ has a similar meaning to receiving. _ Consumer_ is a program
95
+ that mostly waits to receive messages. On our drawings it's shown with "C":
92
96
93
97
94
98
<center ><div class =" dot_bitmap " >
@@ -108,26 +112,30 @@ sends a message and one that receives and prints it.
108
112
Our overall design will look like:
109
113
110
114
<center ><div class =" dot_bitmap " >
111
- <img src =" http://github.com/rabbitmq/rabbitmq-tutorials/raw/master/_img/b3f3e23007aca653c04def0f8e859d18 .png " alt =" Dot graph " width =" 363 " height =" 125 " />
115
+ <img src =" http://github.com/rabbitmq/rabbitmq-tutorials/raw/master/_img/8ba5b12cebea4a4a081e50e3789a5114 .png " alt =" Dot graph " width =" 338 " height =" 125 " />
112
116
</div ></center >
113
117
114
118
119
+ Producer sends messages to the "test" queue. The consumer receives
120
+ messages from that queue.
121
+
115
122
> #### RabbitMQ libraries
116
123
>
117
124
> RabbitMQ speaks AMQP protocol. To use Rabbit you'll need a library that
118
125
> understands the same protocol as Rabbit. There is a choice of libraries
119
126
> for almost every programming language. Python it's not different and there is
120
127
> a bunch of libraries to choose from:
128
+ >
121
129
> * [ py-amqplib] ( http://barryp.org/software/py-amqplib/ )
122
130
> * [ txAMQP] ( https://launchpad.net/txamqp )
123
131
> * [ pika] ( http://github.com/tonyg/pika )
124
132
>
125
133
> In this tutorial we're going to use ` pika ` . To install it you can use
126
134
> [ ` pip ` ] ( http://pip.openplans.org/ ) package management tool:
127
135
>
128
- > $ sudo pip install -e git+http://github.com/tonyg/pika.git#egg=pika
136
+ > $ sudo pip install -e git+http://github.com/tonyg/pika.git#egg=pika
129
137
>
130
- > If you don't have ` pip ` , you may want to install it.
138
+ > If you don't have ` pip ` , you may need to install it.
131
139
>
132
140
> * On Ubuntu:
133
141
>
@@ -142,13 +150,14 @@ Our overall design will look like:
142
150
143
151
144
152
<center ><div class =" dot_bitmap " >
145
- <img src =" http://github.com/rabbitmq/rabbitmq-tutorials/raw/master/_img/090975cc54ab88a30c0bb4d47611b674 .png " alt =" Dot graph " width =" 278 " height =" 125 " />
153
+ <img src =" http://github.com/rabbitmq/rabbitmq-tutorials/raw/master/_img/89f8023288762c3383ef0ca36e039944 .png " alt =" Dot graph " width =" 253 " height =" 125 " />
146
154
</div ></center >
147
155
148
156
149
157
150
158
Our first program ` send.py ` will send a single message to the queue.
151
- The first thing we need to do is connect to RabbitMQ server.
159
+ The first thing we need to do is to establish a connection with
160
+ RabbitMQ server.
152
161
153
162
<div ><pre ><code class =' python ' >#!/usr/bin/env python
154
163
import pika
@@ -159,27 +168,26 @@ connection = pika.AsyncoreConnection(pika.ConnectionParameters(
159
168
channel = connection.channel()</code ></pre ></div >
160
169
161
170
162
-
163
- Whenever we send a message we need to make sure the recipient queue exists.
164
- RabbitMQ will just trash the message if can't deliver it. So, we need to
165
- create a queue to which the message will be delivered. Let's name this queue
166
- _ test_ :
171
+ We're connected now. Next, before sending we need to make sure the
172
+ recipient queue exists. If we send a message to non-existing location,
173
+ RabbitMQ will just trash the message. Let's create a queue to which
174
+ the message will be delivered, let's name it _ test_ :
167
175
168
176
<div ><pre ><code class =' python ' >channel.queue_declare(queue='test')</code ></pre ></div >
169
177
170
178
171
179
172
180
At that point we're ready to send a message. Our first message will
173
- contain a string _ Hello World!_ and we want to send it to our _ test _
174
- queue.
181
+ just contain a string _ Hello World!_ , we want to send it to our
182
+ _ test _ queue.
175
183
176
- In RabbitMQ a message never goes directly to the queue, it always
184
+ In RabbitMQ a message never can be send directly to the queue, it always
177
185
needs to go through an _ exchange_ . But let's not get dragged by the
178
- details - you can read more about _ exchanges_ in third part of this
179
- tutorial. All we need to know now is how to use a default exchange
180
- identified by an empty string. That exchange is a special one that
186
+ details - you can read more about _ exchanges_ in [ third part of this
187
+ tutorial] ( http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/python/tutorial-three.md ) . All we need to know now is how to use a default exchange
188
+ identified by an empty string. This exchange is special - it
181
189
allows us to specify exactly to which queue the message should go.
182
- The queue name is specified by the ` routing_key ` variable :
190
+ The queue name needs to be specified in the ` routing_key ` parameter :
183
191
184
192
<div ><pre ><code class =' python ' >channel.basic_publish(exchange='',
185
193
routing_key='test',
@@ -188,42 +196,39 @@ print " [x] Sent 'Hello World!'"</code></pre></div>
188
196
189
197
190
198
191
- [ (full send.py source)] ( http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/python/send.py )
192
-
193
199
### Receiving
194
200
195
201
196
202
197
203
<center ><div class =" dot_bitmap " >
198
- <img src =" http://github.com/rabbitmq/rabbitmq-tutorials/raw/master/_img/e8c961b5097209b7e18281754f6403a4 .png " alt =" Dot graph " width =" 278 " height =" 125 " />
204
+ <img src =" http://github.com/rabbitmq/rabbitmq-tutorials/raw/master/_img/bc21efaa5981805f4038b3065e15e6b4 .png " alt =" Dot graph " width =" 253 " height =" 125 " />
199
205
</div ></center >
200
206
201
207
202
208
203
209
Our second program ` receive.py ` will receive messages from the queue and print
204
210
them on the screen.
205
211
206
- The code responsible for connecting to Rabbit is the same as the previous example.
207
- You can copy the first 7 lines .
212
+ Again, first we need to connect to RabbitMQ server. The code
213
+ responsible for connecting to Rabbit is the same as previously .
208
214
209
- # ... connection code is the same, copy first 7 lines from send.py ...
210
-
211
- Just like before, in the beginning we must make sure that the
212
- queue exists. Creating a queue using ` queue_declare ` is idempotent - you can
213
- run the command as many times you like, and only one queue will be created.
215
+ Next step, just like before, is to make sure that the
216
+ queue exists. Creating a queue using ` queue_declare ` is idempotent - we can
217
+ run the command as many times you like, and only one will be created.
214
218
215
219
<div ><pre ><code class =' python ' >channel.queue_declare(queue='test')</code ></pre ></div >
216
220
217
221
218
- You may ask why to declare queue again - we have already declared it
219
- in our previous code. We could have avoided that if we always run the
220
- ` send.py ` program before this one. But we're not sure yet which
222
+ You may ask why to declare the queue again - we have already declared it
223
+ in our previous code. We could have avoided that if we were sure
224
+ that the queue already exists. For example if ` send.py ` program was
225
+ run before. But we're not yet sure which
221
226
program to run as first. In such case it's a good practice to repeat
222
227
declaring the queue in both programs.
223
228
224
229
> #### Listing queues
225
230
>
226
- > Sometimes you may want to see what queues does RabbitMQ store and how many
231
+ > You may want to see what queues does RabbitMQ store and how many
227
232
> messages are in them. You can do it using the ` rabbitmqctl ` tool:
228
233
>
229
234
> $ sudo rabbitmqctl list_queues
@@ -233,17 +238,19 @@ declaring the queue in both programs.
233
238
234
239
235
240
236
- Receiving messages from the queue is a bit more complex. Whenever we receive
237
- a message, a ` callback ` function is called. In our case
238
- this function will print on the screen the contents of the message.
241
+ Receiving messages from the queue is more complex. It works by subscribing
242
+ a ` callback ` function to a queue. Whenever we receive
243
+ a message, this ` callback ` function is called by the Pika library.
244
+ In our case this function will print on the screen the contents of
245
+ the message.
239
246
240
247
<div ><pre ><code class =' python ' >def callback(ch, method, header, body):
241
248
print " [x] Received %.20r" % (body,)</code></pre></div>
242
249
243
250
244
251
245
- Next, we need to tell RabbitMQ that this particular callback function is
246
- interested in messages from our _ test_ queue:
252
+ Next, we need to tell RabbitMQ that this particular callback function should
253
+ receive messages from our _ test_ queue:
247
254
248
255
<div ><pre ><code class =' python ' >channel.basic_consume(callback,
249
256
queue='test',
@@ -254,17 +261,65 @@ For that command to succeed we must be sure that a queue which we want
254
261
to subscribe to exists. Fortunately we're confident about that - we've
255
262
created a queue above - using ` queue_declare ` .
256
263
264
+ The ` no_ack ` parameter will be described [ later on] ( http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/python/tutorial-two.md ) .
265
+
257
266
And finally, we enter a never-ending loop that waits for data and runs callbacks
258
267
whenever necessary.
259
268
260
269
<div ><pre ><code class =' python ' >print ' [*] Waiting for messages. To exit press CTRL+C'
261
270
pika.asyncore_loop()</code ></pre ></div >
262
271
263
272
264
- [ (full receive.py source)] ( http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/python/receive.py )
265
273
266
274
### Putting it all together
267
275
276
+
277
+ Full code for ` send.py ` :
278
+ <div ><pre ><code class =' python ' >#!/usr/bin/env python
279
+ import pika
280
+
281
+ connection = pika.AsyncoreConnection(pika.ConnectionParameters(
282
+ host='127.0.0.1',
283
+ credentials=pika.PlainCredentials('guest', 'guest')))
284
+ channel = connection.channel()
285
+
286
+
287
+ channel.queue_declare(queue='test')
288
+
289
+ channel.basic_publish(exchange='',
290
+ routing_key='test',
291
+ body='Hello World!')
292
+ print " ; [ x] Sent 'Hello World!'" ; </code ></pre ></div >
293
+
294
+ [ (send.py source)] ( http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/python/send.py )
295
+
296
+
297
+ Full ` receive.py ` code:
298
+ <div ><pre ><code class =' python ' >#!/usr/bin/env python
299
+ import pika
300
+
301
+ connection = pika.AsyncoreConnection(pika.ConnectionParameters(
302
+ host='127.0.0.1',
303
+ credentials=pika.PlainCredentials('guest', 'guest')))
304
+ channel = connection.channel()
305
+
306
+
307
+ channel.queue_declare(queue='test')
308
+
309
+ print ' [ * ] Waiting for messages. To exit press CTRL+C'
310
+
311
+ def callback(ch, method, header, body):
312
+ print " ; [ x] Received %.20r" ; % (body,)
313
+
314
+ channel.basic_consume(callback,
315
+ queue='test',
316
+ no_ack=True)
317
+
318
+ pika.asyncore_loop()</code ></pre ></div >
319
+
320
+ [ (receive.py source)] ( http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/python/receive.py )
321
+
322
+
268
323
Now we can try out our programs. First, let's send a message using our
269
324
` send.py ` program:
270
325
@@ -278,10 +333,10 @@ Let's receive it:
278
333
[x] Received 'Hello World!'
279
334
280
335
Hurray! We were able to send our first message through RabbitMQ. As you might
281
- have noticed, the ` receive.py ` program didn 't exit. It will stay ready to
282
- receive further messages. Try to run ` send.py ` in a new terminal!
336
+ have noticed, the ` receive.py ` program doesn 't exit. It will stay ready to
337
+ receive further messages. Try to run ` send.py ` again in a new terminal!
283
338
284
339
We've learned how to send and receive a message from a named
285
- queue. It's time to move on to part 2 of this tutorial and build a
286
- simple _ task queue_ .
340
+ queue. It's time to move on to [ part 2] ( http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/python/ tutorial-two.md )
341
+ and build a simple _ task queue_ .
287
342
0 commit comments