之前的教程中,我们改进了日志系统。我们没有使用只能进行虚拟广播的扇出交换器,而是使用了直接交换器,并获得了选择性接收日志的可能性。
虽然使用直接交换改进了我们的系统,但它仍然有局限性——它不能基于多个标准进行路由。
在我们的日志系统中,我们可能不仅希望根据严重性订阅日志,还希望根据发出日志的源订阅日志。您可能从 syslog unix 工具知道这个概念,它根据严重性(info/warn/crit...)和设施(auth/cron/kern...)路由日志。
这会给我们很大的灵活性——我们可能只想听来自“cron”的严重错误,但也想听来自“kern”的所有日志。
要在我们的日志系统中实现它,我们需要了解更复杂的主题交换。
 
发送到主题交换的消息不能有任意的 routing_key - 它必须是一个单词列表,由点分隔。词可以是任何东西,但通常它们指定与消息相关的一些特征。一些有效的路由键示例:“ stock.usd.nyse ”、“ nyse.vmw ”、“ quick.orange.rabbit ”。路由键中的单词可以有任意多个,最多不超过 255 个字节。
绑定密钥也必须采用相同的形式。主题交换背后的逻辑 类似于直接交换——使用特定路由键发送的消息将被传递到与匹配绑定键绑定的所有队列。然而,绑定键有两个重要的特殊情况:
  • *(星号)只能代替一个词。
  • (hash) 可以替代零个或多个单词。
 

一、创建一个exchange

 
 

二、消息产生端

#!/usr/bin/env python
import pika
import sys
import json
import datetime def get_message():
# 产生消息入口处
for i in range(100): # 生成100条消息
# 生成三种类型的消息
for str_t in ['quick.orange.rabbit','lazy.orange.elephant','quick.orange.fox','lazy.brown.fox','lazy.pink.rabbit','quick.brown.fox','quick.orange.new.rabbit']: # 生成多种类型的消息
message = json.dumps({'id': "%s-90000%s" % (str_t, i), "amount": 100 * i, "name": "%s" % str_t,
"createtime": str(datetime.datetime.now())})
producer(message, str_t) def producer(message, routing_key):
# 登陆并创建信道
connection = pika.BlockingConnection(
pika.ConnectionParameters(virtual_host='/melon_demo', host='82.156.19.94', port=5672,
credentials=pika.PlainCredentials('guest', 'guest')))
channel = connection.channel()
channel.exchange_declare(exchange='topic_logs', exchange_type='topic',durable=True)
channel.basic_publish(exchange='topic_logs', routing_key=routing_key, body=message)
print(" [x] Sent %r:%r" % (routing_key, message))
connection.close() if __name__ == "__main__":
get_message() # 程序执行入口

三、消息接收端【lazy.#】

#!/usr/bin/env python
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(virtual_host='/melon_demo', host='82.156.19.94', port=5672,
credentials=pika.PlainCredentials('guest', 'guest')))
channel = connection.channel() channel.exchange_declare(exchange='topic_logs', exchange_type='topic',durable=True) result = channel.queue_declare('', exclusive=True)
queue_name = result.method.queue # for binding_key in ['lazy.#','lazy.*']:
channel.queue_bind(exchange='topic_logs', queue=queue_name, routing_key='lazy.#')
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(queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()

四、消息接收端【.orange.

#!/usr/bin/env python
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(virtual_host='/melon_demo', host='82.156.19.94', port=5672,
credentials=pika.PlainCredentials('guest', 'guest')))
channel = connection.channel() channel.exchange_declare(exchange='topic_logs', exchange_type='topic',durable=True) result = channel.queue_declare('', exclusive=True)
queue_name = result.method.queue # for binding_key in ['*.orange.*','*.*.rabbit','lazy.#','lazy.*']:
channel.queue_bind(exchange='topic_logs', queue=queue_name, routing_key='*.orange.*') print(' [*] Waiting for Orange. To exit press CTRL+C') def callback(ch, method, properties, body):
print(" [x] %r:%r" % (method.routing_key, body)) channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()

五、消息接收端【..rabbit】

#!/usr/bin/env python
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(virtual_host='/melon_demo', host='82.156.19.94', port=5672,
credentials=pika.PlainCredentials('guest', 'guest')))
channel = connection.channel() channel.exchange_declare(exchange='topic_logs', exchange_type='topic',durable=True) result = channel.queue_declare('', exclusive=True)
queue_name = result.method.queue # for binding_key in ['*.orange.*','*.*.rabbit','lazy.#','lazy.*']:
channel.queue_bind(exchange='topic_logs', queue=queue_name, routing_key='*.*.rabbit') print(' [*] Waiting for *.*.rabbit. To exit press CTRL+C') def callback(ch, method, properties, body):
print(" [x] %r:%r" % (method.routing_key, body)) channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()

六、运行截图

RBMQ案例五:主题模式的更多相关文章

  1. RabbitMQ详解(三)------RabbitMQ的五种模式

    RabbitMQ详解(三)------RabbitMQ的五种模式 1.简单队列(模式) 上一篇文章末尾的实例给出的代码就是简单模式. 一个生产者对应一个消费者!!! pom.xml ​ 必须导入Rab ...

  2. RabbitMQ六种队列模式-主题模式

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

  3. RabbitMQ传输原理、五种模式

    本文代码基于SpringBoot,文末有代码连接 .首先是一些在Spring Boot的一些配置和概念,然后跟随代码看下五种模式 MQ两种消息传输方式,点对点(代码中的简单传递模式),发布/订阅(代码 ...

  4. rabbitmq五种模式详解(含实现代码)

    一.五种模式详解 1.简单模式(Queue模式) 当生产端发送消息到交换机,交换机根据消息属性发送到队列,消费者监听绑定队列实现消息的接收和消费逻辑编写.简单模式下,强调的一个队列queue只被一个消 ...

  5. WPF案例 (五) 对控件界面使用倒影

    原文:WPF案例 (五) 对控件界面使用倒影 在这个程序里对5个2D控件界面应用了垂直倒影,边缘模糊化和模型变换,在本例中,这5个2D控件为Border, 各包含了一幅Image,界面如下图所示,源码 ...

  6. ActiveMQ队列、主题模式区别

    1.ActiveMQ队列模式如下图,生产者创建消息到消息中间件,再“均分给消费者”. 2.ActiveMQ主题模式如下图,生产者创建消息到消息中间件,消费者会接受到订阅的主题中所有的消息.在主题模式下 ...

  7. RabbitMQ消息队列(八)-通过Topic主题模式分发消息(.Net Core版)

    前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用.如果对direct模式下通过routingkey来匹配消息的模式已经有一定了解那fanout也很好 ...

  8. 队列模式&主题模式

    # RabbitMQ 消息中间件 **Advanced Message Queuing Protocol (高级消息队列协议** The Advanced Message Queuing Protoc ...

  9. RabbitMQ (七) 订阅者模式之主题模式 ( topic )

    主题模式和路由模式很像 路由模式是精确匹配 主题模式是模糊匹配 依然先通过管理后台添加一个交换机. 生产者 public class Producer { private const string E ...

  10. activeMQ队列模式和主题模式的Java实现

    一.队列模式 生产者 import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destina ...

随机推荐

  1. C# 超大数据量导入 SqlBulkCopy

    1 public static void ImportTempTableDataIndex(DataSet ds,string TempTableName,string strSqlConnectio ...

  2. 数据挖掘 | 数据隐私(3) | 差分隐私 | 差分隐私概论(上)(Intro to Differential Privacy 1)

    L3-Intro to Differential Privacy 从这节课开始就要介绍差分隐私算法了. 随机响应(Randomized Response) 场景提出 假若你是某一门课的教授,你希望统计 ...

  3. 面试题54. 二叉搜索树的第k大节点

    地址:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/ <?php /** 面试题54. ...

  4. 【ABAQUS Material】density 行为

    1.overview 进行eigenfrequency . transient dynamic analysis. transient heat transfer analysis. adiabati ...

  5. manim边学边做--线性变换的场景类

    在数学可视化领域,Manim的LinearTransformationScene类为线性代数教学提供了强大的工具. 这个专门设计的场景类继承自VectorScene,通过内置的变换动画和坐标系管理,能 ...

  6. 【MIPS】经典指令块集锦

    Directives声明变量值存储 容易将数据段地址和地址上的内容搞混 .data fibs: .space 48 # allocate 12 * 4 = 48 Byte memory, store ...

  7. [tldr] 配置windows terminal使用git bash

    windows terminal默认使用power shell作为shell,但是power shell不好用,还是习惯linux的命令行行为. 参考Windows Terminal 配置 Git B ...

  8. angular+ionic项目,页面无法滚动的问题

    在做angular+ionic+cordova项目时,遇到一个小小的问题,就是内容做完,页面无法滚动,导致内容显示不完整 首先我检查了样式,发现并没有给页面定死高度,再次检查结构发现,我并没有用ion ...

  9. gorm stdErr = sql: Scan error on column index 0, name "total": converting NULL to float64 is unsupported

    前言 使用 gorm 查询时,报错:stdErr = sql: Scan error on column index 0, name "total": converting NUL ...

  10. Django实战项目-学习任务系统-用户管理

    接着上期代码框架,开发第6个功能,用户管理,查看用户信息和学生用户属性值,尤其是总积分值,还可以查看积分流水明细,完成任务奖励积分,兑换物品消耗积分. 第一步:编写第6个功能-用户管理 1,编辑模型文 ...