Python一路走来 RabbitMQ
一:介绍:(induction)
Rabbitmq 是一个消息中间件。他的思想就是:接收和发送消息。你可以把它想成一个邮政局。当你把你的邮件发送到邮箱的,首先你需要确认的是:邮政员先生能把你的邮件发送给你想发送的地方。在这个比喻中,rabbitmq就是一个邮箱、一个邮政局、一个邮递员。
在这里rabbitmq和传统邮政局的区别:rabbitmq不处理信纸。取而代之的是:接收、储存、发送二进制数的消息。
rabbitmq和消息用如下专业术语:
生产者意思发送。A程序发送消息被称为:producer。我们可以用如下图标表示生产者:
aaarticlea/png;base64,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" alt="" width="242" height="75" />
队列的意思:邮箱。他是rabbitmq的内部结构。虽然消息经过rabbitmq和你的程序。他也可以储存在队列里。一个队列的消息绑定是没有限制。他可以储存任何你喜欢的数据。他本质上就是无限大的缓存区。很多生产者可以发送消息到队列中,而消费者们可以尝试从队列里获取
数据。队列A 如下图标表示,队列名字标注上面:
aaarticlea/png;base64,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" alt="" />
消费者:意思是接收数据 。一个消费者类型的程序大多数是在等待数据的接收。我们用如下C图标表示:
aaarticlea/png;base64,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" alt="" />
如上的生产者、消费者、消息队列大多数是存储在不同的机器上。
二:hello word
一个helloword 队列并不复杂。他只是发送消息、接收消息、打印输出到屏幕。为了实现这些功能,我们需要2个程序:一个是发送消息;另一个接收消息并打印输出消息。
我们的设想如下:
aaarticlea/png;base64,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" alt="" />
生产者发送消息到hello队列,消费者从hello队列获取消息。
三:发送
我们第一个程序是send.py。他将帮我们发送一个简单的消息到队列里。我们首先需要做的是和rabbitmq server端建立起连接。
aaarticlea/png;base64,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" alt="" />
建立连接的程序片段如下:
1 #!/usr/bin/env python
2 import pika
3
4 connection = pika.BlockingConnection(pika.ConnectionParameters(
5 'localhost'))
6 channel = connection.channel()#通信频道
我们现在就可以进行连接了。把消息发送到本地机器(localhost)上,如果我们相连接消息中间件(rabbitmq)在不同的机器上。我们可以在上面的connection里把localhost写成ip地址或者可以解析的主机名字。
第二行的代码,是通信频道。在我们发送的时候需要确认接收的队列是否存在。如果我们发送的消息到不存在的队列,这个消息会被丢弃。让我们一起建立一个接收消息的队列。我们命令为:hello。
1 channel.queue_declare(queue='hello')
现在我们可以准备发送消息了。我们第一条消息,只是一个简单的字符串hello world!我们把这个字符串发送到我们的hello队列里。
在rabbitmq里,消息不是直接发送到队列里。他发送的到队列里是通过exchange。exchange先不做过多介绍。我们现在需要知道怎么使用默认的exchange,是由空字符串(“”)来表示。这个是特殊的exchange,他帮助我们把消息发送到我们想发送的队列中。
在默认的exchange中,我们需要填写我们要发送的队列的名字。即routiing_key这个参数中。
1 channel.basic_publish(exchange='',
2 routing_key='hello',
3 body='Hello World!')
4 print(" [x] Sent 'Hello World!'")
在关闭连接的时候,需要确认我们的消息已经发送到rabbitmq 或者我们的消息已经从网络缓存写入硬盘中。
1 connection.close()
四:接收
aaarticlea/png;base64,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" alt="" />
我们第二个程序:receive.py,他将接收我们消息从hello队列里并输出到屏幕里。
当然了,首先我们需要连接到rabbitmq服务端,连接的代码和之前的代码是一样的。
下一步,我们需要确认队列是否存在,我们可以根据参数:queue_declare来声明和创建一个新的队列。
你可以运行多次这样的命令,但是真正只创建只有一个队列。
1 channel.queue_declare(queue='hello')
你会有疑问,在productor程序已经创建一个队列为什么这里还写这个。这是因为我们不确定我们的程序运行顺序,比如说先运行productor的话,队列hello创建,但是如果先运行consumer的程序的话,该队列就不存在。所以这里在productor和consumer再次写这段代码
避免这个问题,如果队列存在,该条创建命令不会生效。
note:如何查看我们的rabbitmq里有哪些队列呢?
我们可以在rabbitmq服务器上运行如下命令:可以查看当前rabbitmq有哪些queue和以及每个queue有多少个消息,可以使用:需要管理员用户哦。
1 [root@localhost ~]# rabbitmqctl list_queues
2 Listing queues ...
3 hello1 0
4 lmd 0
5 ...done.
在接收消息的程序里能复杂些,实际上是callback函数订阅queue的时候,才起作用。不管什么时候我们获取消息的时候,这个callback函数都会被模块Pika的库调用。callback函数在我们的程序里只是简单的打印输出到屏幕上。
1 def callback(ch, method, properties, body):
2 print(" [x] Received %r" % body)
接下来,我们需要告诉rabbitmq,这个我们自定义的callback函数将会接收我们的队列hello的消息。
1 channel.basic_consume(callback,
2 queue='hello',
3 no_ack=True)#这里的no_ack 意思是消息不做回执确认。
如上的命令想成功运行需要确保我们订阅的hello队列存在。 我们在上面代码的中已经用queue_declare 来声明和创建了这个队列了。
最后我们根据我们的需要,来执行一个循环语句等待接收消息和运行我们的callback函数如果你需要的话。
1 print(' [*] Waiting for messages. To exit press CTRL+C')
2 channel.start_consuming()#循环接收我们的消息,接收之后并执行我们的callback函数。
我们把之前的代码整合在一起:
PUT TOGTHER:
send.py 代码:
#!/usr/bin/env python
import pika connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.queue_declare(queue='hello') channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()
receive.py代码:
1 #!/usr/bin/env python
2 import pika
3
4 connection = pika.BlockingConnection(pika.ConnectionParameters(
5 host='localhost'))
6 channel = connection.channel()
7
8 channel.queue_declare(queue='hello')
9
10 def callback(ch, method, properties, body):
11 print(" [x] Received %r" % body)
12
13 channel.basic_consume(callback,
14 queue='hello',
15 no_ack=True)
16
17 print(' [*] Waiting for messages. To exit press CTRL+C')
18 channel.start_consuming()
现在我们可以在一个终端运行我们的代码。用我们的send.py程序来发送消息:
1 $ python send.py
2 [x] Sent 'Hello World!'
生产者程序会每执行一次结束。让我们来接收消息:
1 $ python receive.py
2 [*] Waiting for messages. To exit press CTRL+C
3 [x] Received 'Hello World!'
Cheers!我们已经成功发送第一个消息通过rabbitmq,神奇吧,小伙伴!我相信聪明的你已经注意到:recvied.py 程序并没有执行一次结束,依然保持准备接收从hello队列里的接下来发的消息,这是由于参数:channel.start_consuming()的功劳。当然你可以用Ctrl-c来终止。
二:进阶
一:工作队列(Work Queues)
aaarticlea/png;base64,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" alt="" />
在第一部分的时候,我们已经写了发送和接收消息从一个hello队列中的2个程序。这部分将介绍一个工作队列,用于分配一些复杂的任务处理。
这个工作队列的主要思想是:避免创建一些可以立马的执行完毕的任务,而是一些需要耗时等待的一些任务。一会介绍我们任务。我们将把我们的任务封装(encapsulate)成消息并把消息发送给对垒。
然后,通过后台运行一个程序来队列获取任务并且执行该任务。如果你运行多个这样的程序的话,任务消息将会被这个程序所平分(shared)。
这个场景多数会用在web程序里,那种不能短时间被短暂的http请求所执行的任务。
二:准备(preparing)
在先前我们程序中我们简单的发送的"Hello World!"。现在我们将发送字符串来支撑我们的复杂任务。我们这个只是模拟一下,我们手里并没有复杂的任务。你可以想象成一个图片的大小的调整或者一个pdf文件的渲染(rendered)。让我们一起伪造一下该过程是一个
繁忙的过程。通过time模块的sleep()函数来实现。我们将通过字符串的句点.个数来模拟我们任务的复杂度。没存在一个句点我们将通过sleep函数来耗时一秒。比如说:hello... 将会耗时3秒。
我们可以通过我们之前的send.py程序稍作修改即可。通过随意杜撰的字符串来实现这个任务的复杂,通过命令行并发送给我们的工作队列(task_queue),我们把发送的脚本叫做: new_task.py:
1 import sys
2
3 message = ' '.join(sys.argv[1:]) or "Hello World!"
4 channel.basic_publish(exchange='',
5 routing_key='task_queue',
6 body=message,
7 properties=pika.BasicProperties(
8 delivery_mode = 2, # make message persistent
9 ))
10 print(" [x] Sent %r" % message)
我们之前的receive.py脚本也需要做一些更改,他需要从task_queue获取一个任务,他需要通过检索消息体中字符串的句点的个数来运行我们的任务。我们将下面的程序叫做:worker.py:
1 import time
2
3 def callback(ch, method, properties, body):
4 print(" [x] Received %r" % body)
5 time.sleep(body.count(b'.'))
6 print(" [x] Done")
三:循环获取任务策略:
使用任务队列的一个好处是我们可以很容易平行(parallelise)执行我们的任务。如果我们创建一个备份日志的任务。我们可以通过多加一些工作程序来解决。
首先我们尝试通过2个窗口来运行我们的woker.py脚本在同一时间内。这2个窗口就是我们2个消费者:C1 和 C2。
1 shell1$ python worker.py
2 [*] Waiting for messages. To exit press CTRL+C
1 shell2$ python worker.py
2 [*] Waiting for messages. To exit press CTRL+C
接下来我们将会发布一些任务消息。一旦你启动消息者程序,你就可以通过new_task.py来发布一些消息。
1 shell3$ python new_task.py First message.
2 shell3$ python new_task.py Second message..
3 shell3$ python new_task.py Third message...
4 shell3$ python new_task.py Fourth message....
5 shell3$ python new_task.py Fifth message.....
我们一起看下我们消费者接收哪些消息从我们task_queue队列中:
1 shell1$ python worker.py
2 [*] Waiting for messages. To exit press CTRL+C
3 [x] Received 'First message.'
4 [x] Received 'Third message...'
5 [x] Received 'Fifth message.....'
1 shell2$ python worker.py
2 [*] Waiting for messages. To exit press CTRL+C
3 [x] Received 'Second message..'
4 [x] Received 'Fourth message....'
通过上面的观察,默认情况下RabbitMQ将会把每个消息发送下一个消费者。顺序的,每个消费者获得的任务都是等差数列(相邻2个消息(包含数字)相减的值相等)。这种方式的分发消息我们循环发送消息。你可以通过多运行几个这样的woker.py来验证。
三:消息确认(Message acknowledgment)
执行一个任务耗时几秒钟。你会有一个疑问:如果我们一个消费者在执行任务的时候需要耗时很长时间的过程中,死掉的话。目前我们的代码,一旦rabbitmq发送消息给消费者之后,他会立刻把该消息从队列中移除。或者你杀死一个正在运行的woker的话,我们将会丢失这个消息,
以及我们将会丢失所有发送给这个woker的所有消息。
但是我们并不想丢失这些任务消息。如果worker(消费者)死掉的话,我们想把丢失的消息再次发送给另一个存活的woker并执行(消费者)。为了确保我们的消息不能被丢失,RabbitMQ给我们提供了一个acknowkedgement(消息确认)。在消费者收到消息并执行完的时候会发送一个
ack 确认告诉RabbitMQ 已经接收到并处理过这个消息。而RabbitMQ会把这个消息删除掉。
如果一个消费者因为以下原因而死掉:
1)通信chanel关闭。
2)连接关闭。
3)TCP连接丢失。
因为如上原因没有给RabbitMQ发送ack确认的话,RabbitMQ会认为这个消息没有被执行完,会把这个消息重新放在相应的消息队列中。如果这个时候,还有在线的消费者,这个消息会被很快重新发送给在线的消费者。这种方式保证了如果消费者因为某些原因而死亡,消息不被丢失。
消息没有超时时间,只有当消费者挂掉的时候,RabbitMQ才会重新发送消息,即使这个消息被执行很久很久的时间。
默认情况,消息的acknowledgments是被打开的。之前的代码例子中,我们通过:no_ack=True的标识来关闭这个功能。也就是说默认情况这个参数:no_ack=Flase.
在适当的时候,把no_ack=True移走这个标识,让woker程序在执行完消息之后,发送ack确认。
1 def callback(ch, method, properties, body):
2 print " [x] Received %r" % (body,)
3 time.sleep( body.count('.') )
4 print " [x] Done"
5 ch.basic_ack(delivery_tag = method.delivery_tag)#发送ack跟rabbitMQ消息确认。
6
7 channel.basic_consume(callback,
8 queue='hello')
使用如上代码,我们可以确认,即使你把其中的一个正在处理消息的woker程序杀死或者Ctrl+C终止程序。不会丢失任何消息。没有ack的确认的消息,一会会被重新发送给另一个woker。
四:消息持久化(Message durability)
我们已经学会,当消费者挂掉的时候,保证消息不丢失的情况。但是当RabbitMQ挂掉的时候消息还是会被丢失。
如果RabbitMQ没有做任何设置,当RabbitMQ停止或者崩溃的话,他会丢失所有队列以及消息。除非你做一些特殊设置。
需要做2件事情,保证消息不丢失:
1)标记队列为持久化:已经存在的RabbitMQ队列不能重新定义为持久化。
2)标记消息为持久化。
首先我们做第一件事情,保证RabbitMQ不会丢失我们的队列。因为我们需要在创建的队列的声明这个队列是持久化队列(durable)
1 channel.queue_declare(queue='hello', durable=True)#在创建队列的时候声明队列是持久化队列。
即使这个命令我们正确执行之后,但是并没有生效。因为我们已经定义一个队列hello,在声明创建的时候并没有说明这个队列是持久化。RabbitMQ并不允许重新定义一个已经存在的队列的不同的参数。他将会返回一个错误给程序。
那么我们重新定义一个不存在的队列。
1 channel.queue_declare(queue='work_queue', durable=True)
同样这个声明需要在生产者和消费者程序上需要写这行代码。
做了如上声明,可以保证RabbitMQ在被重启的时候,队列不会被丢失。接下来我们需要标记消息为持久化。
方法之前的代码中已经出现:
消息持久化:
properties=pika.BasicProperties(
delivery_mode = 2,
)
1 channel.basic_publish(exchange='',
2 routing_key="task_queue",
3 body=message,
4 properties=pika.BasicProperties(
5 delivery_mode = 2, # make message persistent
6 ))
注意(NOTE):
如上的标记消息为持久化,并不能完全保证消息不丢失,即使你告诉RabbitMQ需要把消息写入磁盘。但是仍然有一小段时间内RabbitMQ没有把消息写入磁盘中。RabboitMQ并没有把每条消息写入磁盘中。也许会把消息写入缓存中。而并不是真正写入硬盘中。
这个标记消息持久化并不健全。但是对于简单任务队列来说已经足够。如果你需要保证消息不被丢失,可以参考下:publisher confirms.
五:公平分配(Fair dispatch)
也许你发现上面的循环分配方式并不是我们想要的。比如,如下场景:
当所有的基数消息很繁重,相反偶数消息很轻巧。这就会导致一个woker 处理很缓慢,而另一个woker几乎没有任何消息需要等待处理。RabbitMQ并不知道消息情况,他依然会这样分配消息给woker。
这种情况,是因为RabbitMQ只是分配消息当消息进入队列的时候,RabbitMQ并查看消费者有多少没有确认的消息。他只是盲目(blindly)分配消息给消费者。
aaarticlea/png;base64,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" alt="" />
为避免这个情况,我们可以用:basic.qos方法来设置prefetch_count=1。这个设置告诉RabbitMQ不要给woker每次多于一个消息。换句话说,不要在woker当前处理的消息没有返回ack确认的时候,在分发一个消息给woker。也就是说当woker空闲的时候才会被分配
一个消息。
1 channel.basic_qos(prefetch_count=1)
注意(NOTE)队列的大小:
如果所有wokers都很繁忙的情况下,队列会被填满。你需要时刻注意这个问题,这种情况:
1)添加更多的wokers。
2)或者更改其他的消息分配策略。
代码合并(Putting it all together):
Final code of our new_task.py script:
1 #!/usr/bin/env python
2 import pika
3 import sys
4
5 connection = pika.BlockingConnection(pika.ConnectionParameters(
6 host='localhost'))
7 channel = connection.channel()
8
9 channel.queue_declare(queue='task_queue', durable=True)##队列持久化。
10
11 message = ' '.join(sys.argv[1:]) or "Hello World!"
12 channel.basic_publish(exchange='',
13 routing_key='task_queue',
14 body=message,
15 properties=pika.BasicProperties(
16 delivery_mode = 2, # make message persistent消息持久化。
17 ))
18 print(" [x] Sent %r" % message)
19 connection.close()
And our worker:
1 #!/usr/bin/env python
2 import pika
3 import time
4
5 connection = pika.BlockingConnection(pika.ConnectionParameters(
6 host='localhost'))
7 channel = connection.channel()
8
9 channel.queue_declare(queue='task_queue', durable=True)
10 print(' [*] Waiting for messages. To exit press CTRL+C')
11
12 def callback(ch, method, properties, body):
13 print(" [x] Received %r" % body)
14 time.sleep(body.count(b'.'))
15 print(" [x] Done")
16 ch.basic_ack(delivery_tag = method.delivery_tag)#消息回执确认。
17
18 channel.basic_qos(prefetch_count=1)#公平分配策略。
19 channel.basic_consume(callback,
20 queue='task_queue')
21
22 channel.start_consuming()#循环等待消息。
使用消息确认和公平策略去设置我们工作队列。设置持久化选项保证我们的任务存活即使RabbitMQ被重启。
三:订阅和发布
上面的例子,我们创建一个队列。队列将每个任务精确的发送给每个woker。这部分我们将做一个完全不一样的。我们将一个消息发送一个多个消费者。这部分叫做发布和订阅。
为了说明这个部门我们创建一个简单的日志收集系统。他将包含2部分。第一部分是发送日志消息,第二部分接收日志消息并打印输出日志消息。
我们接收程序拷贝多个来模拟多个消费者去接收消息。这种方式我们运行一个接收日志和将日志写入磁盘中。同时我们将运行另一个接收和输出屏幕的接收程序。
基本上,发布的日志消息将会广播给所有的接收者。
一:Exchanges
之前的我们介绍的部分中,我们发送一个消息给队列和从队列中接收消息。现在我们接收下RabbitMQ消息传输模式:
我们简单回顾下我们介绍的知识:
1)生产者是一个发送消息的应用程序。
2)队列是一个存储消息的buffer。
3)消费者是一个接收消息的应用程序。
消息传输模式核心思想是:在RabbitMQ中生产者从来都不是将消息直接发送给队列。实际上生产者并不知道自己的发送的给那个队列。
而是生产者只能讲消息发送exchange。exchange是很简单的东西。一方面他从生产这接收消息,另一方面消息推送给队列。exchange必须准确知道从生产者接收的消息去向。消息被追加到一个特殊的队列中?多个特殊队列?或者被丢弃?
所有的规则都是在exchange类型中定义的。
aaarticlea/png;base64,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" alt="" width="454" height="133" />
这里有几个有效的exchange类型:
direct, topic, headers and fanout。
首先我们来学习下:
一:fanout类型。
定义:
1 channel.exchange_declare(exchange='logs',
2 type='fanout')
fanout类型的exchange很简单,从他的名字你也许猜到他的含义。他只是广播所有的消息给绑定他的所有队列并队列接收这些消息。这正是我们设置的日志收集系统所想要的。
注意(note):
列出所有RabbitMQ所有的exchange。
1 rabbitmqctl list_exchanges
2 Listing exchanges ...
3 direct
4 amq.direct direct
5 amq.fanout fanout
6 amq.headers headers
7 amq.match headers
8 amq.rabbitmq.log topic
9 amq.rabbitmq.trace topic
10 amq.topic topic
11 ...done.
在这列表中有一些以amq.* exchange。和一些没有名字的exchange。这些是默认创建的exchange
二:Nameless exchange
在之前的部分的时候,我们并没有讲过exchange,但是我们仍然可以将消息发送到队列中。这是因为我们用的是默认exchange.也就是说之前写的:exchange='',空字符串表示默认的exchange。
之前的代码结构:
1 channel.basic_publish(exchange='',
2 routing_key='hello',
3 body=message)
exchange = 参数表示exchange 的名字,空字符串只是默认或者没有的exchange:消息被路由到队列根据:routing_key. 如果routing_key的值存在的话。
现在,我们可以用我们自己命名的exchange来代替默认的exchange。
1 channel.basic_publish(exchange='logs',
2 routing_key='',
3 body=message)
二:临时队列(Temporary queues)
是否还记得之前我们使用的队列,每个队列都有自己的名字(还记得hello和task_queue?)队列的名字对于我们来说很重要,我们将指引wokers到相同的队列。给一个队列命名很重要,当你想把这个队列给生产者和消费者使用。
但是对于我们日志来说无所谓,我们只想接收所有的日志消息。而不是一个“片段”。同样我们只是关系即将发送的消息而不是过去的消息。解决这个问题我们需要2件事情:
1)首先我们需要连接到RabbitMQ.需要一个全新的。空队列。为了实现这个我们创建一个随机队列名字,是一个好方法。让RabbitMQ选择一个随机的队列名字给我们。
我们可以给queue_declare不提供任何参数来实现:
1 result = channel.queue_declare()
然后用result对象的方法method.queue创建一个随机队列名字。比如:名字就想:amq.gen-JzTY20BRgKO-HjmUJj0wLg。
2)第二件事情,当消费者断开连接的时候,这个队列需要销毁。专用标识:
1 result = channel.queue_declare(exclusive=True)##标识这个队列在断开连接的时候被销毁。
三:绑定(Bindings)
aaarticlea/png;base64,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" alt="" />
我们已经创建一个fanout类型的exchange和一个随机队列。现在需要告诉exchange发送消息给我们的队列。exchange和queue之间的关系叫做binding 绑定。
1 channel.queue_bind(exchange='logs',
2 queue=result.method.queue)
那现在logsexchange将消息发送到我们的queue。
你可以用命令行显示:
1 rabbitmqctl list_bindings.
四:把所有设置整合在一起(Putting it all together)
aaarticlea/png;base64,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" alt="" />
生产者程序,是发送日志消息。看起来和之前没多少区别。重要的区别:现在我们将消息发布到我们的logs exchange而不是没有名字默认的exchange。我们同样需要一个routing_key当我们发送消息的时候。但是在fanout类型中这个可以忽略。
emit_log.py code:
1 import pika
2 import sys
3
4 connection = pika.BlockingConnection(pika.ConnectionParameters(
5 host='localhost'))#创建连接。
6 channel = connection.channel()#创建通信频道。
7
8 channel.exchange_declare(exchange='logs',
9 type='fanout')#创建一个fanout类型的exchange。
10
11 message = ' '.join(sys.argv[1:]) or "info: Hello World!"
12 channel.basic_publish(exchange='logs',#指定exchange。
13 routing_key='',#routing_key可以忽略。
14 body=message)
15 print(" [x] Sent %r" % message)
16 connection.close()
正如你所见,当我们建一个连接之后我们声明一个exchange。此步必不可少,如果发布到一个不存在的exchange会报权限问题。
消息会因为exchange没有绑定队列而丢失。但是对于我们来说我们已经绑定的不存在这个问题。如果没有consumer在接收消息。消息会被我们丢弃。
The code for receive_logs.py:
1 #!/usr/bin/env python
2 import pika
3
4 connection = pika.BlockingConnection(pika.ConnectionParameters(
5 host='localhost'))#创建连接。
6 channel = connection.channel()#创建通信频道。
7
8 channel.exchange_declare(exchange='logs',
9 type='fanout')#再次声明一个exchange 以及类型。
10
11 result = channel.queue_declare(exclusive=True)#创建一个队列,在断开连接的时候该队列会删除掉。
12 queue_name = result.method.queue#队列的名字。
13
14 channel.queue_bind(exchange='logs',
15 queue=queue_name)#exchange绑定队列。
16
17 print(' [*] Waiting for logs. To exit press CTRL+C')
18
19 def callback(ch, method, properties, body):
20 print(" [x] %r" % body)
21
22 channel.basic_consume(callback,
23 queue=queue_name,
24 no_ack=True)#设置不消息确认。
25
26 channel.start_consuming()#循环等待接收消息。
我们已经完成我们的需求。如果你想把日志保存到文件中。打开窗口运行如下命令:
1 $ python receive_logs.py > logs_from_rabbit.log
如果你想在你屏幕看见消息,你可以打开新的窗口 运行如下命令:
1 $ python receive_logs.py
做了如上操作我们就可以发送我们日志消息了。
1 $ python emit_log.py
使用rabbitmqctl list_bindings 你可以看到代码绑定的我们想要的队列。如果你运行2个终端接收消息 看起来像这样:
1 rabbitmqctl list_bindings
2 Listing bindings ...
3 exchange amq.gen-3l_KUxC92rzcjB5QVvDcfg queue amq.gen-3l_KUxC92rzcjB5QVvDcfg []
4 exchange amq.gen-QlgGf1orpKVxFePt5u-8pw queue amq.gen-QlgGf1orpKVxFePt5u-8pw []
5 exchange hello1 queue hello1 []
6 exchange lmd queue lmd []
7 logs_fanout exchange amq.gen-3l_KUxC92rzcjB5QVvDcfg queue amq.gen-3l_KUxC92rzcjB5QVvDcfg []
8 logs_fanout exchange amq.gen-QlgGf1orpKVxFePt5u-8pw queue amq.gen-QlgGf1orpKVxFePt5u-8pw []
9 ...done.
五:Routing
先前的例子我们建立一个简单的日志收集系统。日志消息以广播的形式发送到所有的消费者。
在这个章节我们将会加入一个新的策略:让订阅者接收一些特定的消息。比如说:我们只将严重级别的日志写入磁盘,同样也满足将所有接收的 所有日志消息打印输出到屏幕上。
一:绑定(Bindings)
在之前的例子我们已经创建了绑定了,你的代码类似如下:
1 channel.queue_bind(exchange=exchange_name,
2 queue=queue_name)
这种绑定是建立在exchange和队列之间的。这种简单的设置,使队列只对从exchange发送的消息感兴趣。
绑定创建了一个特殊的routing_key参数。区别之前的绑定的队列名字,我们叫他为绑定关键字。如下是我们创建的绑定关键字的代码:
1 channel.queue_bind(exchange=exchange_name,
2 queue=queue_name,
3 routing_key='black')
也就是说绑定官架子依赖于exchange的类型。在fanout类型中routing_key这个关键字是空字符串,忽略这个值。
四:关键字绑定(Direct exchange)
我们之前的日志收集系统是将所有的消息以广播的形式发送到所有消费者。
我们设想是按照severity来筛选我们的日志消息。比如:我们只想要这样的脚本,只有接受到严重错误级别的消息写入硬盘中。不想写入info或者warning级别的日志消息而浪费磁盘空间。
我们之前用fanout类型的exchange 并没有给我们太多的伸缩性,他只能盲目把消息发送给消费者。
接下来我们将会用diect类型的exchange来代替 fanout。direct exchange 的算法很简单:消息会按照routing_key的配置的关键字准确匹配的队列,才发送给这个队列。
如下图所示:
aaarticlea/png;base64,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" alt="" />
这种设置,我们可以看到名字为X的xchange绑定2个队列:Q1、Q2。Q1队列被绑定一个关键字orange。Q2队列绑定2个关键字,一个关键字是black 一个是green.
这种设置的RabbitMQ。生产者发送的消息给exchange包含关键字,比如说orange,消息将会路由到Q1这个队列。如果消息携带的关键字包含black或者green的时候将会路由到Q2队列上。其他的关键字的消息将会被丢弃。
多次绑定(Multiple bindings)
aaarticlea/png;base64,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atwYASClUo/zcFx5lJOc/H2/fiq1GhffVQce1JqUlNSzZ8/27du7uLiEhITwM41rNMz9+/fHjPHr0GG9lVUOHtetY0EvEkVJpdlt2640MenSpcvxdu1WN2hAmZrul0jSRaJovTpficVxNB1jZZXdqtXMefOWflCDIiu9/Yloowa1odFoGA5mz579zaipFpeeiROBUrDUGyOM8tYLOSuKUomulYmul1ExGu2GDd0iD5ZOBNGloq/tx8xZsqTqbvATpGq1wXFcBysrwb17eDieHk0a+MjcXGRs/M/OVatQx44IAKlUehgIDxABENy6RU2YcOvWrep56rh3716PHj0QQgihRo0aWVpaOjs7b9myheMgJyfH1naiufkpmSyZphU6Rhu4fkkkipJKM7/8csjnn9uamJh+990cXD2lb4ddilLQtFwmS+zc+fc+fdzz8vKw85gKXloD6t2KcpycPw+/U/sA/q/a+19K9VKSf7sYPPWIRqN56QCijZrShkajYTkubM+e1o4eXc8+oBOBjn1L0wXvDDoWZLlgdR+s7oAkGQcleoUdQCs4OgG6RRS2sO5zNSqKBByVRdVqg2XZRq1bC/EsIO8Qbdy7hxBC7dujNm1Qu3aoRw906RLiOMQP6NPtVOXRxqNHX/r5TZkyZcv27aGhoRurjNDQ0C1btsyfP79jx45CodDAwABV0Lx58549e4lEoiZNrDp3PiiRJIlEMTp2t8ViqKiqOmds3KpRo97dul2j6XhcPaWvOUQiuURyw9z8nKnpoPv377/108QTWKleQV0BH2+96h5t/VRdZzbt4g/HlDgvoo0q1cYbPlOO48qUyh8GDuq4K0qcDOJYnZoxKDlLx3Fdz/3dZIiXceuOJl0t260+KophqDi92z8oOUvfhM5/JNG237/PPRK0qfJoo1GrVoifY0pfbdy6hQwN0Z9/oiNH0NmzKD0d6XseHG3gF0+eNPL39/LyWr9p08qVK1dXGatWrQoNDQ0KCmrfvj1CqE6dOnXq1Klbt65AIEAIISRECDVtamdmFs5PIqKPNq5LpZnt2q01MmpZr55Z585/SCRpIlH0O2gD9+AyN7/QqtX3/v7+69ev37Zt2549e44dO3bmzJlr164lJCSkp6ffv3//6dOnldggxHHcvxnotRLS9tAbwiCWZbdt22Ztbb1x40bcUwsqplt+9uyZM9FG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" alt="" />
多个队列绑定相同的关键字很完美的结合,在我们的例子中,我们将增加一个black关键字绑定名字是X的exchange和队列Q1. 在这种绑定情况下,direct exchange看起来想fanout模式那样,将消息广播给所有匹配到black的所有列(Q1,Q2)。
发送日志端:(Emitting logs)
我们将用采用direct类型的exchange来重构我们的日志收集系统。取代之前的fanout的模式。我们将提供一个关键字(severity )做为routing_key。这种模式下,我们可以根据我们选择的关键字来接收消息。
首先来看下发送日志消息端:
和之前一样我们首先需要创建一个exchange:
1 channel.exchange_declare(exchange='direct_logs',
2 type='direct')#关键字模式。
接下来我们发布消息:
1 channel.basic_publish(exchange='direct_logs',
2 routing_key=severity,#severity关键字的集合。
3 body=message)
severity可以是一个或者多个关键字,比如说是:“info”,"warning"、“error”。其中的一种或者多种。
订阅端:Subscribing
订阅端的代码和之前的代码没有什么区别,只是我们现在绑定了我们感兴趣关键字的队列。
1 result = channel.queue_declare(exclusive=True)
2 queue_name = result.method.queue
3
4 for severity in severities:
5 channel.queue_bind(exchange='direct_logs',#exchange的名字。
6 queue=queue_name,#随机队列名字。
7 routing_key=severity)#绑定关键字
Putting it all together
aaarticlea/png;base64,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" alt="" />
The code for emit_log_direct.py:
1 #!/usr/bin/env python
2 import pika
3 import sys
4
5 connection = pika.BlockingConnection(pika.ConnectionParameters(
6 host='localhost'))
7 channel = connection.channel()
8
9 channel.exchange_declare(exchange='direct_logs',
10 type='direct')#声明exchange的类型:关键字类型。
11
12 severity = sys.argv[1] if len(sys.argv) > 1 else 'info'
13 message = ' '.join(sys.argv[2:]) or 'Hello World!'
14 channel.basic_publish(exchange='direct_logs',
15 routing_key=severity,#绑定关键字,将消息发送哪个关键字的队列中。
16 body=message)
17 print(" [x] Sent %r:%r" % (severity, message))
18 connection.close()
The code for receive_logs_direct.py:
1 #!/usr/bin/env python
2 import pika
3 import sys
4
5 connection = pika.BlockingConnection(pika.ConnectionParameters(
6 host='localhost'))
7 channel = connection.channel()
8
9 channel.exchange_declare(exchange='direct_logs',
10 type='direct')#声明exchange类型:关键字类型。
11
12 result = channel.queue_declare(exclusive=True)#创建随机队列,当断开连接的这个队列将删除。
13 queue_name = result.method.queue#分配随机队列的名字。
14
15 severities = sys.argv[1:]
16 if not severities:
17 sys.stderr.write("Usage: %s [info] [warning] [error]\n" % sys.argv[0])
18 sys.exit(1)
19
20 for severity in severities:
21 channel.queue_bind(exchange='direct_logs',
22 queue=queue_name,
23 routing_key=severity)#该消费者绑定的关键字。
24
25 print(' [*] Waiting for logs. To exit press CTRL+C')
26
27 def callback(ch, method, properties, body):
28 print(" [x] %r:%r" % (method.routing_key, body))
29
30 channel.basic_consume(callback,
31 queue=queue_name,
32 no_ack=True)#消息没有回执确认。
33
34 channel.start_consuming()#循环等待消息接收。
如果你想你的日志文件只保存warning和error 而不包含info内容。打开终端输入如下命令:
1 $ python receive_logs_direct.py warning error > logs_from_rabbit.log
如你想看所有的日志消息在你终端屏幕上你可以重新打开一个窗口并输入如下命令:
1 $ python receive_logs_direct.py info warning error
2 [*] Waiting for logs. To exit press CTRL+C
或者,你只想接收错误的日志消息,你可以输入以下命令:
1 $ python emit_log_direct.py error "Run. Run. Or it will explode."
2 [x] Sent 'error':'Run. Run. Or it will explode.'
五:模糊匹配模式(Topics模式)
之前我们的日志收集系统,采用fanout模式的 exchange,可以通过广播让消费者接收所有的日志消息,之后我们改成关键字的模式(direct)根据消息的发送的关键字路由到我们的想发送的队列。
即时采用direct 类型的exchange来改善我们的日志收集系统,但是他仍然有局限性:不能讲消息根据多个规则来进行路由。
在我们的日志系统中不仅仅根据关键字(severity)来进行订阅,而是基于源程序发送的日志消息。
你应该了解这种需求多大Unix操作系统中的syslog工具。他就是需要绑定包括关键字(severity (info/warn/crit...))和(auth/cron/kern...)。这种情况。
这个需求给了我们很多筛选条件。我们也许只关心cron日志里的critical errors的消息,和kern的所有日志消息。
为满足上述的需求我们进行的日志收集系统采取topic exchange.
Topic exchange
消息发送给topic类型的exchange时候,不能随意定义routing_key.他必须是一系列的单词列表。由圆点来进行限定。单词可以随意,但通常是填写一些可以表明消息的功能的一些单词,比如说:"stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit"。也可以自定义一些i喜欢的单词,
但是routing_key的长度大小限制在255字节。
绑定的key必须是相同的格式结构,Topic exchange的逻辑和direct(关键字类型)一样,消息在发送的时候需要携带一个特殊的routing_key.并发送到所有的跟exichange绑定的队列相匹配绑定key的队列。
实现这些功能需要做以下2件事情:
1)*匹配一个单词。
2)#可以代替0到多个单词。
最简单例子如下:
aaarticlea/png;base64,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" alt="" />
我们将发送一些消息,消息的内容是形容一些动物。这些消息在发送的时候会携带一个routing_key,routing_key的内容包含3个单词,其中有2个句点(.)。第一个单词在routing_key中形容快速,第2个单词是颜色。第三个单词是物种:"<celerity>.<colour>.<species>".
我们创建3个绑定:Q1绑定关键字:"*.orange.*" Q2:"*.*.rabbit" 和 "lazy.#".
这样绑定的意义是:
1)Q1是表示对所有橘黄色的动物感兴趣。
2)Q2是想接收所有关于兔子以及所有懒惰的东西所有事情。
一个消息中routing_key="quick.orange.rabbit" 会被发送到Q1和Q2.而携带routing_key="lazy.orange.elephant"的消息 ,也同样发送到这2个队列中。
另一方面:携带routing_key= "quick.orange.fox"消息 只能发送到Q1队列。而routing_key="lazy.brown.fox"只能发送到Q2队列。而携带routing_key="quick.brown.fox"的消息没有匹配任何绑定队列,该消息会被丢弃。
如果我们发送的消息携带的routing_key含有一个单词或者四个单词比如:"orange" or "quick.orange.male.rabbit"? 这些消息因为匹配不了任何绑定而会被丢弃。
另一方面像:"lazy.orange.male.rabbit" 即时他有4个单词,单也会匹配Q2而发送到Q2队列中。
注意:模糊匹配(Topic exchange)是一个很强大的策略。
当一个队列绑定的key为”#“ ,这个队列会接收所有内容的消息。在fanout类型的队列中routing_key是无值(”“空字符串)。也就是说fanout模式直接接收所有的消息。
如果在模糊匹配中,绑定的关键字没有"#"和”*“的话,topic类型的exchange和dict(关键字模式)的工作原理是一样的。
Putting it all together
我们将使用topic 类型的exchange在我们的日志收集系统中。 假设(assumption )我们绑定的routing_key有2个关键字:"<facility>.<severity>".
The code for emit_log_topic.py:
1 #!/usr/bin/env python
2 import pika
3 import sys
4
5 connection = pika.BlockingConnection(pika.ConnectionParameters(
6 host='localhost'))
7 channel = connection.channel()
8
9 channel.exchange_declare(exchange='topic_logs',
10 type='topic')#创建topic类型的exchange。模糊匹配。
11
12 routing_key = sys.argv[1] if len(sys.argv) > 1 else 'anonymous.info'
13 message = ' '.join(sys.argv[2:]) or 'Hello World!'
14 channel.basic_publish(exchange='topic_logs',
15 routing_key=routing_key,#绑定关键字
16 body=message)
17 print(" [x] Sent %r:%r" % (routing_key, message))
18 connection.close()
The code for receive_logs_topic.py:
1 #!/usr/bin/env python
2 import pika
3 import sys
4
5 connection = pika.BlockingConnection(pika.ConnectionParameters(
6 host='localhost'))
7 channel = connection.channel()
8
9 channel.exchange_declare(exchange='topic_logs',
10 type='topic')#声明exchange的类型为模糊匹配。
11
12 result = channel.queue_declare(exclusive=True)#创建随机一个队列当消费者退出的时候,该队列被删除。
13 queue_name = result.method.queue#创建一个随机队列名字。
14
15 binding_keys = sys.argv[1:]
16 if not binding_keys:
17 sys.stderr.write("Usage: %s [binding_key]...\n" % sys.argv[0])
18 sys.exit(1)
19
20 for binding_key in binding_keys:
21 channel.queue_bind(exchange='topic_logs',
22 queue=queue_name,
23 routing_key=binding_key)
24
25 print(' [*] Waiting for logs. To exit press CTRL+C')
26
27 def callback(ch, method, properties, body):
28 print(" [x] %r:%r" % (method.routing_key, body))
29
30 channel.basic_consume(callback,
31 queue=queue_name,
32 no_ack=True)
33
34 channel.start_consuming(
当输入如下,会被所有日志消息会被接收:
1 python receive_logs_topic.py "#"
接收所有从“kern”关键字的日志:
1 python receive_logs_topic.py "kern.*"
如果你想所有关于"critical" 日志消息:
1 python receive_logs_topic.py "*.critical"
你可以建立多个绑定:
1 python receive_logs_topic.py "kern.*" "*.critical"
那么发送日志消息端的routing_Key="kern.critical"
1 python emit_log_topic.py "kern.critical" "A critical kernel error"
六 : RPC
在第二节中,我们学习了怎么使用工作队列(work Queues)通过多个消费者执行我们的任务。
但是,如果我们想在运程一台机器上执行一个函数等待函数的返回结果呢?哈哈,这个悲伤的故事。 这种方式叫做运程执行或者RPC。
在这个小章节中我们将使用RabiitMQ 来创建一个RPC远程调用系统:创建一个client端,和一个远程执行的RPC server。我们没一个值得耗时的任务。我们将创建一个仿造RPC服务执行返回一个数字。
客户端接口:
为了说明一个RPC服务是怎么使用和运行的我们定义一个简单的客户端类。他将会揭露 通过发送给RPC 请求,远程调用l方法,客户端并阻塞等待RPC server返回执行结果。
1 fibonacci_rpc = FibonacciRpcClient()
2 result = fibonacci_rpc.call(4)
3 print("fib(4) is %r" % result)
NOTE:
虽然RPC是一个不错的功能对于计算机来说。但是这个功能遭到很多人的诟病。程序不会意识到RPC是本地的函数调用或者是一个缓慢的RPC。这就导致给系统添加了很多没必要复杂的调试。
有如下建议,请思考:
1)确认函数的调用是远程还是本地调用。
2)在你的系统文档中,需要清晰的表达组件之间的依赖关系。
3)当RPC server执行调用时间过长或者挂掉的时候,客户端该怎么处理?
Callback queue(调用队列):
通过RabiitMQ来实现RPC功能很简单。客户端发送请求消息,服务端返回应答消息。为了获得应答消息,客户端需要给RPC server发送一个callback队列和请求消息。我们一起尝试下:
1 result = channel.queue_declare(exclusive=True)#创建随机队列,当我们断开来接的时候,RabbitMQ会把该队列删除掉。(exclusive=True)
2 callback_queue = result.method.queue
3
4 channel.basic_publish(exchange='',
5 routing_key='rpc_queue',
6 properties=pika.BasicProperties(
7 reply_to = callback_queue,#执行结果把结果传入我们创建的随机队列中。
8 ),
9 body=request)
消息属性:
AMQP协议给消息提供了14种不同的属性。下面是我们经常用的几种属性:
1:delivery_mode:使消息持久化。(delivery_mode=2)#持久化包括队列持久化(channel.queue_declare(queue='hello', durable=True)、消息持久化(delivery_mode=2)。以及消息传输过程的消息回执确认。(ch.basic_ack(delivery_tag = method.delivery_tag)#消息回执确认。)
2:content_type:设置消息的编码类型。比如果JSON,他的设置就是application/json.
3:reply_to:通常后面跟存放着调用执行结果的队列名字。
4:correlation_id:用来RPC应答的时候,唯一标识。来确定将结果返回那个主机。
Correlation id
之前建议的时候,我们为每个RPC请求建立一个callback队列。看起来不错,但是有更好的方法,我们为每个客户端单独建立一个callback队列。
如果这样又出现新的问题:反馈的消息他不清楚把结果消息是哪个请求的。那correlation_id 属性就是解决这个问题。我们将设置一个唯一的值给每个请求。当callback队列接收消息的时候会查看这个属性。然后基于这个属性的匹配来确认是那个请求。如果不匹配,返回的消息会被丢弃。
你会问为什么不直接返回错误,而是在callback队列中直接丢弃呢?这是因为,如果RPCserver 在发送完结果消息的时候,如果没有发送回执确认,死掉话,当RPC server重启之后,这个消息请求不会丢失,还会继续处理这个消息。
结构:
aaarticlea/png;base64,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6VHwDwYAivT19U0MCNDfto36HbVQiHp7WbNnb9i0iepeURBlievN49G++IL694+YzpzhOjl1dXW1tLTk5OTExsb6+flxOBwejxcfH19UVDRU78gGAAAZkr7+mjVlCurro34vjU9PnjC53Orqaqo7RhHUJO65c+fYnp6D/fq9owNt24ZcXJChITI2RjweOnduMCtkhoVNmz59xIgRU6dO/eSTT/Lz80WvcgIAgOGmubnZyMoK3bun+K61sxNt3owcHZG+PuJwUFAQ4vMHG7rp6eOnTKG6bxRBTeK6+fmhs2cH1eOdncjXFy1bhm7eRF1dqKUF5eej2bMHtc6bN01sbDT2IcwAAKBmCbt2MZYuHdR+NSIChYejX35Bvb2osRGdPImmTRts4vb1sceNq6iooLp7BoyCxL1z5w7T1hb19g6qx3fuRBERg33bJCajadPy8vLU3ycAAKCBXnrlFVRZOaj9KoOBWluVvq/W2bPnragoqrtnwChI3F27dhnGxAy2x93ckECg9HcRHTgQroXvIgBKhBAFuwWggX755RfW6NGD3alyuejyZeXvqx8+NLKwoLqHBoyCP62ZCxagkycH2910OuroUP67WFs72s1N/X0CgOZQOHEhqoVC4YoVK1auXCnPTEkFBQUzZszAn0y3evXq58+fq6aN8kpLSzNavHiwO9WMDGRqihYtQklJqKwM9fQoa3fNtrO7e/cutV00UBT8hTh5eSlhlAkVJW57uyGbrf4+AUBzQOIORkdHh6en59GjR4k5KSkpXl5enZ2d/ZadOXNmfn7+8+fPGxsbIyIiFi9erMqW9m/btm26W7YoYb/a2IiOHkXr1yMvL2Rrq6wnDI54/XU+n09tFw0UBX8hlg4OSnjqhZsbqqlRfuIKhTQ6XXtvrwYAIZSYmGhra6ujo0PMPHv27IQJEwwMDKytrT/++GP8tmCE0OHDh52cnPT19R0cHL799ltiDUKh8Pbt21wuVzQnnj9/bmFh0dTUJK1eUcT8w4cPOzo66uvrOzo6fvPNN/JvSH19/bx589hstqGhYWBg4JMnT4iKDh48aG9vj4++deXKlePHj48ZM8bAwMDLy+u///0vvtixY8ccHBz09fWdnJwOHz4s7b+B5ORkOzs7ycWk9Vh6evqrr75qaGhobGwcGhra2Ngouc779++PHDnyp59+EgqFNTU1tra2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" alt="" />
整个RPC工作过程是这样:
1)当客户端启动,会建立一个随机回收队列。
2)对于发送RPC请求的消息携带2个属性:1:reply_to 结果返回的队列。;2:correlation_id 为每个请求设置唯一的值。
3)消息请求被发送到rpc_queue队列。
4)RPC server端的woker在rpc_queue队列中等待请求,当请求进来,他会执行请求并把结果消息发送给客户端通过reply_to参数写的队列名字。
5)客户端在callback队列中等待数据返回,当有消息出现,他会查看消息的属性:correlation_id 如果属性值匹配之前的发送请求的消息的correlation_id ,他就会把该消息的结果发送给应用程序。
Putting it all together
The code for rpc_server.py:
1 #!/usr/bin/env python
2 import pika
3
4 connection = pika.BlockingConnection(pika.ConnectionParameters(
5 host='localhost'))
6
7 channel = connection.channel()
8
9 channel.queue_declare(queue='rpc_queue')
10
11 def fib(n):#调用函数
12 if n == 0:
13 return 0
14 elif n == 1:
15 return 1
16 else:
17 return fib(n-1) + fib(n-2)
18
19 def on_request(ch, method, props, body):
20 n = int(body)
21
22 print(" [.] fib(%s)" % n)
23 response = fib(n)
24
25 ch.basic_publish(exchange='',
26 routing_key=props.reply_to,
27 properties=pika.BasicProperties(correlation_id = \
28 props.correlation_id),
29 body=str(response))##发送结果
30 ch.basic_ack(delivery_tag = method.delivery_tag)#消息回执确认。
31
32 channel.basic_qos(prefetch_count=1)#消息分配方式。
33 channel.basic_consume(on_request, queue='rpc_queue')#获得请求的队列参数。
34
35 print(" [x] Awaiting RPC requests")
36 channel.start_consuming()
代码解析:
1)客户端和服务端建立连接和声明队列。
2)声明调用函数。
3)我们声明一个调用返回,这个也是RPC server的核心。当RPC接收客户端消息之后,执行调用函数,并将结果消息返回。
4) 因为我们不可能运行单个server端,如果是多个的话,为了我们采取公平分配消息的原则(当RPCserver执行完一个请求,才接受下一个请求。)
The code for rpc_client.py:
1 #!/usr/bin/env python
2 import pika
3 import uuid
4
5 class FibonacciRpcClient(object):
6 def __init__(self):
7 self.connection = pika.BlockingConnection(pika.ConnectionParameters(
8 host='localhost'))
9
10 self.channel = self.connection.channel()
11
12 result = self.channel.queue_declare(exclusive=True)
13 self.callback_queue = result.method.queue
14
15 self.channel.basic_consume(self.on_response, no_ack=True,
16 queue=self.callback_queue)
17
18 def on_response(self, ch, method, props, body):
19 if self.corr_id == props.correlation_id:
20 self.response = body
21
22 def call(self, n):
23 self.response = None
24 self.corr_id = str(uuid.uuid4())
25 self.channel.basic_publish(exchange='',
26 routing_key='rpc_queue',
27 properties=pika.BasicProperties(
28 reply_to = self.callback_queue,
29 correlation_id = self.corr_id,
30 ),
31 body=str(n))
32 while self.response is None:
33 self.connection.process_data_events()
34 return int(self.response)
35
36 fibonacci_rpc = FibonacciRpcClient()
37
38 print(" [x] Requesting fib(30)")
39 response = fibonacci_rpc.call(30)
40 print(" [.] Got %r" % response)
客户端代码解析:
1)我们建立连接,通信channel和声明消息一个返回的callback队列。
2)我们声明一个callback队列,以便接收RPCserver的请求消息。
3)on_response每次有返回消息的时候都被执行,他的任务很简单,每次检查消息的correlation_id 是否是我们需要的请求结果。如果是,他就把请求结果返回并跳出循环。
4)下一步,我们定义我们主函数call方法,他负责接收请求结果以及发送RPC请求。
5)在这个方法,我们创建一个唯一标识:orrelation_id ,并保存他,on_response函数会用该值比对RPC返回的消息结果。
6)接下来我们发布了一个请求消息。消息携带2个属性:reply_to and correlation_id.
7)然后客户端循环等待RPCserver的请求结果消息。
8)最后我们将结果返回给客户端。
启动RPCserver端:
1 $ python rpc_server.py
2 [x] Awaiting RPC requests
客户端发送请求:
1 $ python rpc_client.py
2 [x] Requesting fib(30)
我们如上代码的比较简单:
比如:
1)如果server端未运行,客户端该如何处理?
2)客户端需要设置超时时间吗?
3)如果服务端发生异常的时候,是否该把异常发送给客户端?
4)怎么处理非法消息呢?
If you want to experiment, you may find the rabbitmq-management plugin useful for viewing the queues.
Python一路走来 RabbitMQ的更多相关文章
- Python一路走来 - python基础 数据类型
对于Python,一切事物都是对象,对象基于类创建 Python数据类型 python主要的数据类型主要包括以下几种类型: (1) 数字型 (2) 字符串 (3) 列表 (4) 元组 (5) 字典 ( ...
- Python一路走来 DAY15 Javascript
JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理. 一 如何编写 ...
- Python 一路走来 Django
Web 框架 (本质:socket) Python web框架 自己实现socket - Tornado 基于wsgi ...
- Python一路走来 线程 进程
Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env pytho ...
- Python一路走来 面向对象1
面向对象: 类,对象 函数放在类里,叫方法 封装 #如何调用 1. 创建对象, 类名() obj= Foo() 2. 通过对象去执行方法 obj.mail("leon@me.com" ...
- Python一路走来 - 模块
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- Python 一路走来 DOM & Jquery
DOM 查找: 直接查找 间接查找 —getElementById ...
- Python 一路走来 HTML CSS Javascript
前端三把利器 HTML -标签 (成对写不容易忘记闭合) 自闭和标签 标签里写个 xx=xx, 表示标签的属性 ...
- Python一路走来 Python算法
冒泡排序: 1,2位置左右比较.大的排右边,继续比较2,3 ...... list=[5,7,2,8,12,1] #print(len(list)) for j in range(len(list)) ...
随机推荐
- Android 自定义控件 EditText输入框两边加减按钮Button
自己封装的一个控件:EditText两边放加减按钮Button来控制输入框的数值 Demo 下载地址: 第一版:http://download.csdn.net/detail/zjjne/674086 ...
- hdu 4856 Tunnels
http://acm.hdu.edu.cn/showproblem.php?pid=4856 这道题就是搜索BFS+状压dp,把所经过的隧道的状态用二进制表示,然后dp就行.bfs求出每两个隧道的最短 ...
- ural 1126 Magnetic Storms
http://acm.timus.ru/problem.aspx?space=1&num=1126 #include <cstdio> #include <cstring&g ...
- MFC关于VS内存释放的定位
全部在App中完成 1.在 App.h 头文件声明 #ifdef _DEBUGprotected: CMemoryState m_msOld, m_msNew, m_msDiff;#endi ...
- 使用ntfs的磁盘映射功能
当年95极受欢迎,是作为一个还算真正的32位系统.之前的3.1都是16位为基础的,很多api支持有限.相应的对于硬件性能的发掘还是值得肯定的 98对于95的取代是成功的,我想重要原因是图形尤其是游戏的 ...
- 【转】中断处理函数中不用disable_irq而用disable_irq_nosync原因
原文网址:http://blog.csdn.net/skyflying2012/article/details/8265869 今天在写触摸屏驱动时在中断处理函数中使用disable_irq关中断发现 ...
- [转载]STL map中的一些基本函数
来源:(http://blog.sina.com.cn/s/blog_61533c9b0100fa7w.html) - C++ map的基本操作和使用_Live_新浪博客 Map是c++的一个标准容器 ...
- Vanya and Triangles 暴力枚举
枚举法: 枚举法是利用计算机速度快, 精度高的特点, 对要解决的问题所有可能情况进行霸道的, 一个不漏检验, 从中找出符合要求的答案. 特点: 1. 得到的结果一定正确. 2. 可能做了很多无用功,效 ...
- New Year Permutation(Floyd+并查集)
Description User ainta has a permutation p1, p2, ..., pn. As the New Year is coming, he wants to mak ...
- 【转】ASP.NET MVC框架下使用MVVM模式-KnockOutJS+JQ模板例子
KnockOutJS学习系列----(一) 好几个月没去写博客了,最近也是因为项目紧张,不过这个不是借口,J. 很多时候可能是因为事情一多,然后没法静下来心来去写点东西,学点东西. 也很抱歉,突然看到 ...