写在前面:
好久不写了,实在是不想写,坚持果然是一件不容易的事情。
我喜欢玩,我更爱学习,然而喜欢是放肆,爱是克制,哈哈。每天上班有些忙就不想动,只想在床上翻滚或者鏖战召唤师峡谷。上班闲着时想了想,一是不方便写,二是忘了很多了---------经过铺垫可以明确的说了:前面都是借口。
白天自己承诺自己晚上要写,虽然没人知道,自己答应自己的事也不能不做啊,晚上复习了一个多小时,现在是实践的时候了:Come on baby,不逼自己一把,你永远不知道自己有多优秀。So anyway,鸡汤香否,哈哈哈,就喜欢转折转的措手不及,这是一种乐观的生活态度。历千劫万险,纵使魂飞魄散,我灵识依在,战百世轮回,纵使六道无常,我依然相信你可以在下面点个赞。
一、RabbitMQ队列
1.RabbitMQ介绍
MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。
消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信。
MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取或者订阅队列中的消息。
2.RabbitMQ安装(Windows)
http://www.rabbitmq.com/install-windows.html
安装python rabbitMQ module
#windows在cmd里执行即可 #(如果不能找不到命令是Python没有设置好环境变量,手动找pip命令) pip install pika or easy_install pika or 源码 https://pypi.python.org/pypi/pika
3.实现最简单的队列通信
send端
import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() #声明queue channel.queue_declare(queue='hello') #n RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange. channel.basic_publish(exchange='', routing_key='hello', #routing_key 就是queue名 body='Hello World!', ) print(" [x] Sent 'Hello World!'") connection.close()
receive端
import pika connection = pika.BlockingConnection(pika.ConnectionParameters( 'localhost')) channel = connection.channel() #You may ask why we declare the queue again ‒ we have already declared it in our previous code. #We could avoid that if we were sure that the queue already exists. For example if send.py program #was run before. But we're not yet sure which program to run first. In such cases it's a good #practice to repeat declaring the queue in both programs. channel.queue_declare(queue='hello') def callback(ch, method, properties, body): print(ch,method,properties)
#ch <pika.adapters.blocking_connection.BlockingChannel object at 0x00000000029A5C50> 管理内存对象地址
#method <Basic.Deliver(['consumer_tag=ctag1.aef832e45baf4745af94ab1b2b75ff22', 'delivery_tag=1', 'exchange=', 'redelivered=False', 'routing_key=hello'])> 具体信息
#properties:<BasicProperties>
print(" --> Received %r" % body) ch.basic_ack(delivery_tag=method.delivery_tag) channel.basic_qos(prefetch_count=1) channel.basic_consume(callback, queue='hello' no_ack=True) print(' [*] Waiting for messages. To exit press CTRL+C') channel.start_consuming()
4.RabbitMQ消息分发轮询
在这种模式下,RabbitMQ会默认把p发的消息依次分发给各个消费者(c),跟负载均衡差不多
import pika connection = pika.BlockingConnection(pika.ConnectionParameters( 'localhost')) channel = connection.channel() #声明queue channel.queue_declare(queue='task_queue') #n RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange. import sys message = ' '.join(sys.argv[1:]) or "Hello World!" channel.basic_publish(exchange='', routing_key='task_queue', body=message, properties=pika.BasicProperties( delivery_mode = 2, # make message persistent )) print(" [x] Sent %r" % message) connection.close()