RabbitMQ基本用法

  • 进程queue用于同一父进程创建的子进程间的通信
  • 而RabbitMQ可以在不同父进程间通信(例如在word和QQ间通信)

示例代码

  • 生产端(发送)
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
#相当于建立一个socket,连接本地的RabbitMQ,默认端口:5672
channel = connection.channel()#声明一个通信管道(信道) #在管道里什么一个queue
channel.queue_declare(queue='hello')#声明一个名称为hello的queue
#通过管道发送消息
channel.basic_publish(exchange='',
routing_key='hello',#queue的名字
body='Hellow Word!')#消息主体
connection.close()#关闭连接
  • 消费端(接收)
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
#不确定生产端或消费端谁先运行,因此为了避免错误,消费端也要申请一个queue
#消费端先运行,如果没申请这个queue,生产端还没建立这个queue,因此报错
channel.queue_declare(queue='hello') def callback(ch,method,properties,body):
#ch,管道(信道)channel的内存地址
#method,设置的一些基本信息
#properties,
#body,消息主体,二进制数据
print(ch,method,properties)
print('[x] Received %r'%body) #声明要收消息
channel.basic_consume(
callback,#如果收到消息就调用回调函数处理消息
queue='hello',#queue的名字
no_ack=True#不确认,是否处理完callback,给rabbitmq返回确认信息
)
#开始收消息
channel.start_consuming()#开启后一直收消息,没消息则卡住

消息分发

RabbitMQ消息分发(一对多)

  • 一个生产者,多个消费者
  • 多个消费者时,是轮询机制,依次分发给消费者。(每个消费者按顺序依次消费)

no_act设置是否确认消息处理完

  • 设置no_act = True,消费者不发送确认信息,RabbitMQ从发送消息队列后,不管消费者是否处理完,删除queue
  • 设置no_act = False,RabbitMQ等待消费者的callback处理完,发送确认信息,如果此时消费者down了,则Rabbit把消息轮询发送给下一个消费者,等待确认才会删除queue
  • 去掉no_act = True(默认为False),需要在回调函数中新增代码,手动向RabbitMQ发送确认信息
  • ch.basic_ack(delivery_tag=method.delivery_tag)

消息持久化

rabbitmq目录下启动cmd,命令:rabbitmqctl.bat list_queues查看当前queue列表

当我们需要消息不会丢失(RabbitMQ server宕机时),需要进行消息持久化

  • 1、在申明队列是加上参数使其持久化,生产者和消费者都需要申明
  • channel.queue_declare(queue='hello',durable=True)队列持久化
  • 2、在生产端发送消息函数时加入参数使消息持久化
  • 消息持久化
channel.basic_publish(
exchange='',
routing_key='hello',#queue的名字
body='Hellow Word!'
porperties=pika.BasicProperties(
delivery_mode=2#使队列里的消息持久化

)#消息主体

广播模式

消息公平分发

  • 如果Rabbit只管按顺序把消息发到各个消费者身上,不考虑消费者负载的话,很可能出现,一个机器配置不高的消费者那里堆积了很多消息处理不完,同时配置高的消费者却一直很轻松。为解决此问题,可以在各个消费者端,配置perfetch=1,意思就是告诉RabbitMQ在我这个消费者当前消息还没处理完的时候就不要再给我发新消息了。

  • 在消费端channel.basic_consume()函数前新增一条代码
  • channel.basic_qos(prefetch_count=1)
  • 解释:如果有2个消费者(a,b),a处理消息比较慢,b比较快;RabbitMQ是轮询发送消息,依次给a一条,给b一条,再给a.....。当在消费者端设置以上代码时,a还在处理,那么RabbitMQ不会给a发送,只会给b

广播模式(消息是实时的,发送时没有启动接收端,消息丢失)

  • 1、发送端将消息发送到RabbitMQ的消息转发器(exchange)
  • 2、转发器(Exchange)遍历所有绑定它的queue,将消息广播给queue
  • 3、接收端从queue里获取接收消息
  • 4、使用此queue的消费者断开后,此queue删除

  • 设置exchange转发器
  • Exchange在定义的时候是有类型的,以决定到底是哪些Queue符合条件,可以接收消息
  • fanout: 所有bind到此exchange的queue都可以接收消息
  • direct: 通过routingKey和exchange决定的那个唯一的queue可以接收消息
  • topic:所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息

给所有bind此exchange的发送消息

  • 发送端
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='logs',
type='fanout')#广播模式,不用申明queue指定queue名
#设置exchange为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()
  • 接收端
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='logs',
type='fanout') result = channel.queue_declare(exclusive=True) #不指定queue名字,rabbit会随机分配一个名字,exclusive=True会在使用此queue的消费者断开后,自动将queue删除
queue_name = result.method.queue#拿到这个随机分配的queue名
channel.queue_bind(exchange='logs',#绑定发送端的exchange
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()

有选择的广播(接受者过滤接收消息exchange type=direct)

  • 生产者
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='direct_logs',
type='direct') severity = sys.argv[1] if len(sys.argv) > 1 else 'info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='direct_logs',
routing_key=severity,
body=message)
print(" [x] Sent %r:%r" % (severity, message))
connection.close()
  • 消费者
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='direct_logs',
type='direct') 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='direct_logs',
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()

细致的消息过滤()

  • 生产者
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='topic_logs',
type='topic') routing_key = sys.argv[1] if len(sys.argv) > 1 else 'anonymous.info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='topic_logs',
routing_key=routing_key,
body=message)
print(" [x] Sent %r:%r" % (routing_key, message))
connection.close()
  • 消费者
  • 参数为#,不过滤收所有
  • mysql.*,收所有mysql开头的消息
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.exchange_declare(exchange='topic_logs',
type='topic') result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue binding_keys = sys.argv[1:]
if not binding_keys:
sys.stderr.write("Usage: %s [binding_key]...\n" % sys.argv[0])
sys.exit(1) for binding_key in binding_keys:
channel.queue_bind(exchange='topic_logs',
queue=queue_name,
routing_key=binding_key) 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()

RabbitMQ基本用法、消息分发模式、消息持久化、广播模式的更多相关文章

  1. RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

    目录 消息存储 消息存储方式 非持久化 持久化 消息存储介质 消息存储与读写方式 消息存储结构 刷盘机制 同步刷盘 异步刷盘 小结 高可用 高可用实现 主从复制 负载均衡 消息重试 顺序消息重试 无序 ...

  2. 工作队列work queues 公平分发(fair dispatch) And 消息应答与消息持久化

    生产者 package cn.wh.work; import cn.wh.util.RabbitMqConnectionUtil; import com.rabbitmq.client.Channel ...

  3. (六)RabbitMQ消息队列-消息任务分发与消息ACK确认机制(PHP版)

    原文:(六)RabbitMQ消息队列-消息任务分发与消息ACK确认机制(PHP版) 在前面一章介绍了在PHP中如何使用RabbitMQ,至此入门的的部分就完成了,我们内心中一定还有很多疑问:如果多个消 ...

  4. rabbitmq消息队列,消息发送失败,消息持久化,消费者处理失败相关

    转:https://blog.csdn.net/u014373554/article/details/92686063 项目是使用springboot项目开发的,前是代码实现,后面有分析发送消息失败. ...

  5. RabbitMQ消息队列(六)-消息任务分发与消息ACK确认机制(.Net Core版)

    在前面一章介绍了在.Net Core中如何使用RabbitMQ,至此入门的的部分就完成了,我们内心中一定还有很多疑问:如果多个消费者消费同一个队列怎么办?如果这几个消费者分任务的权重不同怎么办?怎么把 ...

  6. 轻松搞定RabbitMQ(三)——消息应答与消息持久化

    转自 http://blog.csdn.net/xiaoxian8023/article/details/48710653 这个官网的第二个例子中的消息应答和消息持久化部分.我把它摘出来作为单独的一块 ...

  7. Spring Boot 之 RabbitMQ 消息队列中间件的三种模式

    开门见山(文末附有消息队列的几个基本概念) 1.直接模式( Direct)模式 直白的说就是一对一,生产者对应唯一的消费者(当然同一个消费者可以开启多个服务). 虽然使用了自带的交换器(Exchang ...

  8. Kafka分片存储、消息分发和持久化机制

    Kafka 分片存储机制 Broker:消息中间件处理结点,一个 Kafka 节点就是一个 broker,多个 broker 可以组成一个 Kafka集群. Topic:一类消息,例如 page vi ...

  9. RabbitMQ原理与相关操作(三)消息持久化

    现在聊一下RabbitMQ消息持久化: 问题及方案描述 1.当有多个消费者同时收取消息,且每个消费者在接收消息的同时,还要处理其它的事情,且会消耗很长的时间.在此过程中可能会出现一些意外,比如消息接收 ...

随机推荐

  1. linux文件系统相关概念

    struct task_struct { ......................... struct mm_struct*mm;//内存描述符的指针 struct files_struct *f ...

  2. CF709A Juicer 模拟

    Kolya is going to make fresh orange juice. He has n oranges of sizes a1, a2, ..., an. Kolya will put ...

  3. django内置服务器

    单进程多线程的 多线程用来并发,各个线程之间不会阻塞,每个线程对应一个连接

  4. pytorch tensor与numpy转换

    从官网拷贝过来的,就是做个学习记录.版本 0.4 tensor to numpy a = torch.ones(5) print(a) 输出 tensor([1., 1., 1., 1., 1.]) ...

  5. 自定义Razor 标签

    1.首先需要一个abstract class WebViewPage<T> ,继承系统的 System.Web.Mvc.WebViewPage<TModel> 再定义一个Web ...

  6. ORA-01950:no privileges on tablespace 'USERS'

    ORA-01950:no privileges on tablespace 'USERS' SQL>create user myuser identitied by password; SQL& ...

  7. WIN2008R2 asp.net core的配置

    配置IIS Windows Server上通过“添加角色和功能”,桌面Windows上通过“启用和关闭Windows功能”来安装和配置IIS.确保勾选Web服务和“IIS 管理控制台”: Window ...

  8. oracle db 产品路线图

    Release Schedule of Current Database Releases (文档 ID 742060.1)

  9. 关于python的sort和sorted

    1.sort无返回值,没有新建列表  例子: a=[2,1,3] print("a=",a) b=a.sort() print("a=",a) print(&q ...

  10. 使用PIE对IE6、7、8进行CSS3兼容介绍和经验总结

    下面说说如何对 IE10 以下版本的浏览器进行部分 CSS3 兼容 国外团队开发的兼容插件,去年做项目时才发现,非常强大 主角:PIE.js ,  PIE.htc    两种方法可以实现 官方网站:h ...