RabbitMQ 消息队列

  成熟的中间件RabbitMQ、ZeroMQ、ActiveMQ等等

  RabbitMQ使用erlang语言开发,使用RabbitMQ前要安装erlang语言

  RabbitMQ允许不同应用、程序间交互数据

  python中的Threading queue只能允许单进程内多线程交互的

  python中的MultiProcessing queue只能允许父进程与子进程或同父进程的多个子进程交互

RabbitMQ启动:
  1.windows中默认安装成功,在服务列表中会显示自动启动
  2.Linux中使用命令rabbitmq-server start

RabbitMQ支持不同的语言,对于不同语言有相应的模块,这些模式支持使用开发语言连接RabbitMQ
Python连接RabbitMQ模块有:
  1.pika主流模块
  2.Celery分布式消息队列
  3.Haigha提供了一个简单的使用客户端库来与AMQP代理进行交互的方法

使用RabbitMQ前,首先阅读开始文档: http://www.rabbitmq.com/getstarted.html

简单的发送接收实例
  默认情况下,使用同一队列的进程,接收消息方使用轮询的方式,依次获取消息
  对于一条消息的接收来说,只有当接收方收到消息,并处理完消息,给RabbitMQ发送ack,队列中的消息才会删除
  如果在处理的过程中socket断开,那么消息自动转接到下一个接收方

producer.py

__author__ = 'Cq'

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(
'localhost')) #声明一个管道
channel = connection.channel() #声明queue,这个队列在RabbitMQ中生成,发送方和接收方使用同一个队列
channel.queue_declare(queue='hello2', durable=True) #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='hello2',#队列名称
body='Hello World!',
properties=pika.BasicProperties(
delivery_mode = 2, # make message persistent
)
)#body消息内容
print(" [x] Sent 'Hello World!'")
connection.close()

consumer.py

__author__ = 'Cq'

import pika
import time 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.
#发送方和接收方不知道谁首先连接到RabbitMQ,双方连接上来都先声明一个队列
channel.queue_declare(queue='hello2', durable=True) def callback(ch, method, properties, body):
print("recived message...")
# time.sleep(30)
print(" [x] Received %r" % body)
#处理完成消息后,主动要向RabbitMQ发送ack
ch.basic_ack(delivery_tag=method.delivery_tag)
#ch --> 管道内存对象的地址
#method --> 指定各种参数
#properties -->
#python3 socket等发送网络包都是byte格式 #如果队列里还有1条消息未处理完,将不能接收新的消息
channel.basic_qos(prefetch_count=1) #声明接收收消息变量
channel.basic_consume(callback,#收到消息后执行的回调函数
queue='hello2',)
#no_ack=True)#执行完callback函数后,默认会发送ack给RabbitMQ print(' [*] Waiting for messages. To exit press CTRL+C')
#开始接收消息,不停循环接收,没有消息挂起等待
channel.start_consuming()

在RabbitMQ中查看当前队列数
  1.windows中查看队列
  在RabbitMQ安装目录下,sbin下有个管理工具rabbitmqctl.bat可以查看队列和队列中的消息数
  E:\RabbitMQ Server\rabbitmq_server-3.6.14\sbin>rabbitmqctl.bat list_queues
  Listing queues
  hello 1

消息持久化
如果当RabbitMQ服务器宕机了,不允许为处理的消息丢失时
  1.需要在声明队列时,声明为持久队列,只是队列持久化,消息未能持久化
    channel.queue_declare(queue='hello',durable=True)

  2.需要在发送端发送消息时声明
    channel.basic_publish(exchange='',
    routing_key='hello', #队列名称
    body='Hello World!', #body消息内容
    properties=pika.BasicProperties(
    delivery_mode = 2, # make message persistent
    #..这里可以添加附带参数,客户的通过回调函数的位置参数prop.参数名获取
    ))

消息处理配置
  对于不同性能的机器,处理消息量大小不同
  判断接收方消息队列里是否有未处理的消息,如果队列里还有1条消息未处理完,将不能接收新的消息
  channel.basic_qos(prefetch_count=1)

发送广播消息
  使用exchange,exchange的类型决定如果发送广播消息,它就是一个转发器
    类型:
      fanout: 所有bind到此exchange的queue都可以接收消息
      direct: 通过routingKey和exchange决定的那个唯一的queue可以接收消息
      topic:所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息
      headers: 通过headers 来决定把消息发给哪些queue

  fanout纯广播,只要bind到exchange的queue都能收到广播消息
    ☆发送的消息只广播发送一次
    channel.exchange_declare(exchange='log', type='fanout')
    channel.basic_publish(exchange='log',
    routing_key='',
    body=message)

  实例:

  fanout_producer.py

__author__ = 'Cq'
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='logs',
exchange_type='fanout') message = ' '.join(sys.argv[1:]) or "info: Hello World!"
channel.basic_publish(exchange='logs',
routing_key='',
body=message)
print(" [x] Sent %r" % message)
connection.close()

  fanout_consumer.py

__author__ = 'Cq'
import pika connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='logs',
exchange_type='fanout') #不指定queue名字,rabbit会随机分配一个名字,exclusive=True会在使用此queue的消费者断开后,自动将queue删除
#此queue名唯一,且只接收广播消息,当不需要接收时,能自动销毁
result = channel.queue_declare(exclusive=True)
#不需要queue名,只要绑定到转发器就能接收消息 queue_name = result.method.queue channel.queue_bind(exchange='logs',
queue=queue_name) print(' [*] Waiting for logs. To exit press CTRL+C') def callback(ch, method, properties, body):
print(" [x] %r" % body) channel.basic_consume(callback,
queue=queue_name,
no_ack=True) channel.start_consuming()

  topic过滤内容广播,队列只接收关心的消息

  实例:

  topic_producer.py

__author__ = 'Cq'

import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='topic_logs1',
exchange_type='topic') #默认发送的消息格式为xxx.info
severity = sys.argv[1] if len(sys.argv) > 1 else 'test_message.info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='topic_logs1',
routing_key=severity,
body=message)
print(" [x] Sent %r:%r" % (severity, message))

  topic_consumer.py

__author__ = 'Cq'

import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='topic_logs1',
exchange_type='topic') result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue severities = sys.argv[1:]
if not severities:
sys.stderr.write("Usage: %s [info] [warning] [error]\n" % sys.argv[0])
sys.exit(1) for severity in severities:
channel.queue_bind(exchange='topic_logs1',
queue=queue_name,
routing_key=severity) print(' [*] Waiting for logs. To exit press CTRL+C') def callback(ch, method, properties, body):
print(" [x] %r:%r" % (method.routing_key, body)) channel.basic_consume(callback,
queue=queue_name,
no_ack=True) channel.start_consuming()

 过滤条件设置

To receive all the logs run:
python receive_logs_topic.py "#" To receive all logs from the facility "kern":
python receive_logs_topic.py "kern.*" Or if you want to hear only about "critical" logs:
python receive_logs_topic.py "*.critical" You can create multiple bindings:
python receive_logs_topic.py "kern.*" "*.critical" And to emit a log with a routing key "kern.critical" type:
python emit_log_topic.py "kern.critical" "A critical kernel error"
发送端
python topic_producer.py xxx.info messagexxxx
python topic_producer.py xxx.warngin messagexxxx
python topic_producer.py xxx.error messagexxxx 接收端
python topic_consumer.py *.info
python topic_consumer.py *.warngin
python topic_consumer.py *.error
python topic_consumer.py *.*

参考博客:http://www.cnblogs.com/alex3714/articles/5248247.html

Python与RabbitMQ交互的更多相关文章

  1. 用 Python、 RabbitMQ 和 Nameko 实现微服务

    用 Python. RabbitMQ 和 Nameko 实现微服务 原创 07-17 17:57 首页 Linux中国 "微服务是一股新浪潮" - 现如今,将项目拆分成多个独立的. ...

  2. Python之RabbitMQ的使用

    今天总结一下Python关于Rabbitmq的使用 RabbitMQ官网说明,其实也是一种队列,那和前面说的线程queue和进程queue有什么区别呢? 线程queue只能在同一个进程下进行数据交互 ...

  3. Python操作RabbitMQ

    RabbitMQ介绍 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现的产品,RabbitMQ是一个消息代理,从“生产者”接收消息并传递消 ...

  4. python之RabbitMQ

    一.安装RabbitMQ 1. 安装erlang 1 2 3 4 tar xf otp_src_18.3.tar.gz cd otp_src_18.3 ./configure --prefix=/ma ...

  5. Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy   Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用 ...

  6. python - 操作RabbitMQ

    python - 操作RabbitMQ     介绍 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议.MQ全称为Mess ...

  7. 文成小盆友python-num12 Redis发布与订阅补充,python操作rabbitMQ

    本篇主要内容: redis发布与订阅补充 python操作rabbitMQ 一,redis 发布与订阅补充 如下一个简单的监控模型,通过这个模式所有的收听者都能收听到一份数据. 用代码来实现一个red ...

  8. Python之路第十二天,高级(4)-Python操作rabbitMQ

    rabbitMQ RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消息队列(M ...

  9. Python和Excel交互

    Python和Excel交互 使用的python包为XlsxWriter 下载的链接 https://pypi.python.org/pypi/XlsxWriter 初级的例子: def write_ ...

随机推荐

  1. 洛谷 [P1402] 酒店之王

    有两个约束条件的二分图匹配 我们回忆一下二分图匹配的匈牙利算法的具体流程,它是通过寻找增广路来判断最大匹配数的,我们再观察一下题目中的两个条件,只有两个条件都满足,才算找到一条增广路,所以我们可以分别 ...

  2. ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql' mysql> use mysql

    show databases;select user,password,host from user;我们想通过 查看存在"mysql"数据库中的user表来查看我们的msql数据 ...

  3. 3.C++内联函数,默认参数,占位参数

    本章主要内容: 1)内联函数(替代宏代码段) 2)默认参数 3)占位参数 1.C++的内联函数分析 1.1讲解内联函数之前,首先回忆下之前讲的define宏定义: 之前讲过宏定义会经过预处理器进行文本 ...

  4. C语言之prinf的用法

    1. n换行字符 1).直接输出内容 printf("哈哈\n"); 2).带参数的输出 int i = 10 ; %d:输入控制符 printf ("%d\n" ...

  5. memcached安装与使用详解

    一.memcache的简介 memcache是高速,分布式的内存缓存服务器 php的缓存方式一般可以使用memcache技术和redis技术,其中各有优劣,因不同的情况而选择较为适合的缓存技术,其中m ...

  6. java thread 线程锁同步,锁,通信

    12.线程同步 当多个线程访问同一个数据时,非常容易出现线程安全问题.这时候就需要用线程同步 Case:银行取钱问题,有以下步骤: A.用户输入账户.密码,系统判断是否登录成功 B.用户输入取款金额 ...

  7. sql server在一个字段相同值时,另一个字段结果拼接

    如下字段红框里的信息都一样的,通过转换实现字段拼接 SELECT formmain_id,(SELECT field0040+';' FROM formson_5489 WHERE formmain_ ...

  8. Python自动化--语言基础7--操作日志、加密、发送邮件、线程、生产者消费者

    1.操作日志 logging.basicConfig:日志的统一处理器,对日志的输出格式和方式做配置日志级别等级CRITICAL > ERROR > WARNING > INFO & ...

  9. c++实现一个小算法

    题目:有n个格子,每个格子里有坦克,坦克有两滴血,你向格子里投掷炸弹,每次命中坦克他掉一滴血并随机像左或者右移动一个格子,问最少炸几次能把全部坦克炸完. 题解:先向偶数格子投掷炸弹,所有的坦克全跑到奇 ...

  10. PHP秒杀系统全方位设计(一)

    秒杀系统特点人多商品少时间短流量高外挂机器[黄牛和非黄牛] 技术分析瞬间高并发的处理能力多层次的分布式处理能力人机交互与对抗[12306验证码图片] 技术选型分析Linux+Nginx+PHP+Mys ...