RabbitMQ RabbitMQ Publish\Subscribe(消息发布\订阅)

1对1的消息发送和接收,即消息只能发送到指定的queue里,但这样使用有些局限性,有些时候你想让你的消息被所有的Queue收到,类似广播的效果,这时候就要用到exchange了

Exchange在定义的时候是有类型的,以决定到底是哪些Queue符合条件,可以接收消息:

  1. fanout:所有bind到此exchange的queue都可以接收消息
  2. direct:通过routingKey和exchange决定的那个唯一的queue可以接收消息
  3. topic:所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息
  4. headers:通过headers 来决定把消息发给哪些queue(这个很少用)

一、fanout订阅发布模式(广播模式)

这种模式是所有绑定exchange的queue都可以接收到消息(纯广播的,所有消费者都能收到消息)

1、生产者(fanout_produce):

因为生产者是以广播的形式,所以这边不需要声明queue

import pika
#创建socket实例,声明管道
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
channel = connect.channel() #声明exchange的名字和类型
channel.exchange_declare(exchange="practice",
exchange_type="fanout") #广播一个消息
channel.basic_publish(
exchange="practice",
routing_key='',
body="hello word"
) print("send hello word") connect.close()

2、消费者(fan_consumers):

消费者这边要声明一个唯一的queue_name的对象,并且从对象中获取queue名(每个唯一的queue就代表这一个收音机,锁定着FM频道(exchange))

import pika
#创建socket链接,声明管道
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
channel = connect.channel()
#声明exchange名字和类型
channel.exchange_declare(exchange="practice", exchange_type="fanout")
#rabbit会随机分配一个名字,exclusive=True会在使用此queue的消费者断开后,自动将queue删除,result是queue的对象实例
result = channel.queue_declare(exclusive=True) # 参数 exclusive=True 独家唯一的
queue_name = result.method.queue
#绑定exchange, 相当于打开收音机,锁定了一个FM频道
channel.queue_bind(exchange="practice",
queue=queue_name) #回调函数
def callback(ch,method,properties,body):
print("{0}".format(body))
#消费信息
channel.basic_consume(callback,
queue=queue_name,
no_ack=True)
#开始消费
channel.start_consuming()

注:

生产者发送广播是实时的,消费者需要提前等待生产者发生消息,这个又叫订阅发布,收音机模式,就像只有收音机打开了才能听到锁定的FM频道,但是如果在节目开始一段时间,再打开收音机的话,之前的节目就收听不到了

二、direct订阅发布模式(广播模式)

RabbitMQ还支持根据关键字发送,即:队列绑定关键字,发送者将数据根据关键字发送到消息exchange,exchange根据 关键字 判定应该将数据发送至指定队列。

1、生产者(direct_prodecer)

import pika
import sys
#创建socket实例,声明管道
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
channel = connect.channel() #声明exchange的名字和类型
channel.exchange_declare(exchange="direct_practice",
exchange_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_practice",
routing_key=severity,
body=message
) print("send %s %s" % (severity, message)) connect.close()

2、消费者(direct_consumers)

import pika
import sys
#创建socket链接,声明管道
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
channel = connect.channel()
#声明exchange名字和类型
channel.exchange_declare(exchange="direct_practice", exchange_type="direct")
#rabbit会随机分配一个名字,exclusive=True会在使用此queue的消费者断开后,自动将queue删除,result是queue的对象实例
result = channel.queue_declare(exclusive=True) # 参数 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:
#绑定exchange, 相当于打开收音机,锁定了一个FM频道
channel.queue_bind(exchange="direct_practice",
queue=queue_name,
routing_key=severity) print("Waiting for msg") #回调函数
def callback(ch,method,properties,body):
print("%s %s" % (method.routing_key, body))
#消费信息
channel.basic_consume(callback,
queue=queue_name,
no_ack=True)
#开始消费
channel.start_consuming()

 3、输出

服务端:

C:\Users\dell\PycharmProjects\untitled\practice\rabbitmq_r>python3 direct_producer.py info
send info hello world C:\Users\dell\PycharmProjects\untitled\practice\rabbitmq_r>python3 direct_producer.py warning
send warning hello world

客户端:

C:\Users\dell\PycharmProjects\untitled\practice\rabbitmq_r>python3 direct_consumer.py info
Waiting for msg
info b'hello world'

  

topic定义发布模式(广播模式)

direct把info、error、warning绑定级别把消息区分了,如果想做的更细致的区分,如在Linux上有一个系统日志,所有程序都在这个日志里面打日志。那如果我想知道什么是mysql的发出来的日志,什么是apache发出来的日志。然后mysql日志里面同时是info、warning、error。所以需要做更细的区分,更细致的消息过滤

1、生产者(topic_producer)

import pika
import sys
#创建socket实例,声明管道
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
channel = connect.channel() #声明exchange的名字和类型
channel.exchange_declare(exchange="topic_practice",
exchange_type="topic")
# 关键字,通过三元运算符,获取外部传递的参数
keys = sys.argv[1] if len(sys.argv) > 1 else "info"
message = ' '.join(sys.argv[2:]) or "hello world"
#广播一个消息
channel.basic_publish(
exchange="topic_practice",
routing_key=keys,
body=message
) print("send %s %s" % (keys, message)) connect.close()

  

2、消费者(topic_consumers)

import pika
import sys
#创建socket实例,声明管道
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
channel = connect.channel() #声明exchange的名字和类型
channel.exchange_declare(exchange="topic_practice",
exchange_type="topic")
# 关键字,通过三元运算符,获取外部传递的参数
keys = sys.argv[1] if len(sys.argv) > 1 else "info"
message = ' '.join(sys.argv[2:]) or "hello world"
#广播一个消息
channel.basic_publish(
exchange="topic_practice",
routing_key=keys,
body=message
) print("send %s %s" % (keys, message)) connect.close()

3、输出

服务端:

C:\Users\dell\PycharmProjects\untitled\practice\rabbitmq_r>python3 topic_producer.py mysql.info
send mysql.info hello world C:\Users\dell\PycharmProjects\untitled\practice\rabbitmq_r>python3 topic_producer.py adapter.error
send adapter.error hello world

客户端:

C:\Users\dell\PycharmProjects\untitled\practice\rabbitmq_r>python3 topic_consumers.py mysql.* *.error
Waiting for msg
mysql.info b'hello world'
adapter.error b'hello world'

4、匹配规则

【python】-- RabbitMQ Publish\Subscribe(消息发布\订阅)的更多相关文章

  1. RabbitMQ --- Publish/Subscribe(发布/订阅)

    目录 RabbitMQ --- Hello Mr.Tua RabbitMQ --- Work Queues(工作队列) 前言 在第二篇文章中介绍了 Work Queues(工作队列),它适用于把一个消 ...

  2. Part1.2 、RabbitMQ -- Publish/Subscribe 【发布和订阅】

    python 目录 (一).交换 (Exchanges) -- 1.1 武sir 经典 Exchanges 案例展示. (二).临时队列( Temporary queues ) (三).绑定(Bind ...

  3. 【c#】RabbitMQ学习文档(三)Publish/Subscribe(发布/订阅)

    (本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个任务会被交付给一个[工人].在这一部分我们将做一些完全不同的事情--我们将向多个 ...

  4. fanout(Publish/Subscribe)发布/订阅

    引言 它是一种通过广播方式发送消息的路由器,所有和exchange建立的绑定关系的队列都会接收到消息 不处理路由键,只需要简单的将队列绑定到交换机上 fanout交换机转发消息是最快的,它不需要做路由 ...

  5. 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_8.RabbitMQ研究-工作模式-发布订阅模式-生产者

    Publish/subscribe:发布订阅模式 发布订阅模式: 1.每个消费者监听自己的队列. 2.生产者将消息发给broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将 ...

  6. RabbitMQ六种队列模式-发布订阅模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅 [本文]RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...

  7. redis实现消息发布/订阅

    redis实现简单的消息发布/订阅模式. 消息订阅者: package org.common.component; import org.slf4j.Logger; import org.slf4j. ...

  8. springboot集成redis实现消息发布订阅模式-双通道(跨多服务器)

    基础配置参考https://blog.csdn.net/llll234/article/details/80966952 查看了基础配置那么会遇到一下几个问题: 1.实际应用中可能会订阅多个通道,而一 ...

  9. 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_9.RabbitMQ研究-工作模式-发布订阅模式-消费者

    消费者需要写两个消费者 定义邮件的类 复制以前的代码到邮件类里面进行修改 最上面 声明队列的名称和交换机的名称 监听修改为email 的队列的名称 手机短信接收端 复制一份email的接收端的代码 改 ...

随机推荐

  1. NFS网络文件系统的配置

    NFS网络文件系统的配置 NFS网络文件系统 NFS(network file system)网络文件系统.一种使用于分散式文件协定,有SUN公司开发.功能是通过网络让不同的机器.不同的操作系统能够分 ...

  2. 在ecshop中添加页面,并且实现后台管理

    后台一共需要修改下面的四个文件 admin/template.php admin/includes/lib_template.php languages/zh_cn/admin/template.ph ...

  3. 转:敏捷方式scrum 方案

    http://www.cnblogs.com/taven/archive/2010/10/17/1853386.html 现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... ...

  4. 一步一步学习Unity3d学习笔记系1.3 英雄联盟服务器集群架构猜想

    说到了网游那就涉及到服务器了,时下最火的属英雄联盟了,我也是它的粉丝,每周必撸一把,都说小撸怡情,大撸伤身,强撸灰飞烟灭,也告诫一下同仁们,注意身体,那么他的服务器架构是什么呢,给大家分享一下, 具体 ...

  5. 资深程序员教你如何实现API自动化测试平台!附项目源码!

    原文链接: 1.平时测试接口,总是现写代码,对测试用例的管理,以及测试报告的管理持久化做的不够, 2.工作中移动端开发和后端开发总是不能并行进行,需要一个mock的依赖来让他们并行开发. 3.同时让自 ...

  6. 最新iOS发布App Store详细图文教程~

    网上有很多关于iOS发布上架的教程,但大多比较旧而且不完整.不够清晰.所以整理了一个详细完整的iOS APP发布上架App Store的图文教程.分享给小白到大神路上前进的你我. 上架iOS需要一个苹 ...

  7. cmake 如何生成一个win32工程

    只需要加上下面一句连接选项就可以了. IF(WIN32) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:W ...

  8. STL学习笔记(序列式容器)

    Vector Vector是一个动态数组. 1.Vector的操作函数 构造.拷贝和析构 vector<Elem> c //产生一个空vector ,其中没有任何元素 vector< ...

  9. lvs+keepalived+bind实现负载均衡高可用智能dns

    整体架构: 1.IP地址规划: Dns1:172.28.0.54 Dns2:172.28.0.55 Dr服务器主:172.28.0.57 Dr服务器从:172.28.0.67 Vip:172.28.0 ...

  10. 自动清理DataGuard备机日志

    >> from zhuhaiqing.info #!/usr/bin/bash #删除DataGuard备机归档日志备份 export ORACLE_HOME=/opt/oracle/pr ...