Rabbitmq--topic
一、前言
前面讲到direct类型的Exchange路由规则是完全匹配binding key与routing key,但这种严格的匹配方式在很多情况下不能满足实际业务需求。topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似,也是将消息路由到binding key与routing key相匹配的Queue中,但这里的匹配规则有些不同,它约定:
- routing key为一个句点号“. ”分隔的字符串(我们将被句点号“. ”分隔开的每一段独立的字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”
- binding key与routing key一样也是句点号“. ”分隔的字符串
- binding key中可以存在两种特殊字符“*”与“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)
以上图中的配置为例,routingKey=”quick.orange.rabbit”的消息会同时路由到Q1与Q2,routingKey=”lazy.orange.fox”的消息会路由到Q1与Q2,routingKey=”lazy.brown.fox”的消息会路由到Q2,routingKey=”lazy.pink.rabbit”的消息会路由到Q2(只会投递给Q2一次,虽然这个routingKey与Q2的两个bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息将会被丢弃,因为它们没有匹配任何bindingKey。
二、Exchange topic
topic 和 direct 改动不多,就是routing key 和bind key 需要改一下
生产端:
# -*- coding: UTF-8 -*- import pika # 创建一个连接
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost')) # 创建一个管道
channel = connection.channel() # 声明exchange 及类型
channel.exchange_declare(exchange='topic_log',
exchange_type='topic') # 输入信息,格式为 *.info from *.info test 类似
input_data = input('>>:').strip() # 将输入的信息以空格为分割,转换为列表
data_list = input_data.split(' ') # 三元运算,如果输入信息存在,就使用输入的信息data_list[0],否则用 'anonymous.info'
severity = data_list[0] if len(data_list) > 1 else 'anonymous.info' message = ' '.join(data_list[2:]) or 'hello,world!' # 这里的routing_key就是 data_list[0] 或 'info'
channel.basic_publish(exchange='topic_log',
routing_key=severity,
body=message)
print('[x] Sent %r:%r' % (severity, message)) connection.close()
消费端:
# -*- coding: UTF-8 -*- import pika connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost')) channel = connection.channel() # 声明exchange 及类型
channel.exchange_declare(exchange='topic_log',
exchange_type='topic') result = channel.queue_declare(exclusive=True) queue_name = result.method.queue # 在此我们定义一些列表,列表内容如下
# 这2个列表分别用来测试和routing_key匹配情况
# 第一种只允许接收info的信息
# 第二种允许接收error 和 mysql的信息 # severities = ['*.info']
severities = ['*.error', 'mysql.*'] for severity in severities:
channel.queue_bind(exchange='topic_log',
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()
我们测试时,分别启动两个consumer。
第一个consumer1 中使用 severities = ['*.info']
第二个consumer2中使用 severities = ['*.error', 'mysql.*']
生产者分别输入:
appache.info from appache info test nginx.error from nginx error test mysql.info from mysql info test
可以看到日志信息分别会汇总到两个consumer中, 其中 consumer1 会收到 appache.info 和 mysql.info的信息, 而 consumer2 会收到 nginx.error 和 mysql.info 的信息。
Rabbitmq--topic的更多相关文章
- rabbitmq+topic+java
可参照github代码:https://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/EmitLogTopic.java 1. 新建m ...
- demo rabbitmq topic(主题模式),fanout(广播模式),轮询分发,确认接收Ack处理
//durable = true 代表持久化 交换机和队列都要为true ,持久代表服务重启,没有处理的消息依然存在 //topic 根据不同的routkey 发送和接收信息 //fanout 广播模 ...
- 9.RabbitMQ Topic类型交换机
RabbitMQ消息服务中Topic类型交换机根据通配符路由消息,*代表一个单词,#代表代表0或多个单词. 生产者 消费者 代码 Producer.java package com.tes ...
- RabbitMQ Topic exchange
Topic exchange topic与之前的每个类型都不同(ps:废话每个都是不同的).Topic解决了我们另一个需求.举个例子,有一个做资讯的公司,他们会收集各种科技公司的动态并且第一时间转发出 ...
- RabbitMQ topic 交换器
topic交换器:"."将路由键分为几个标识符,"*"匹配一个, "#"可以匹配多个 1:路由键为*或者#的时候 *:只能匹配单个的字符串 ...
- Java使用RabbitMQ之订阅分发(Topic)
使用RabbitMQ进行消息发布和订阅,生产者将消息发送给转发器(exchange),转发器根据路由键匹配已绑定的消息队列并转发消息,主题模式支持路由键的通配. 生产者代码: package org. ...
- RabbitMQ简单应用の主题模式(topic)
Topic exchange(主题转发器) 发送给主题转发器的消息不能是任意设置的选择键,必须是用小数点隔开的一系列的标识符.这些标识符可以是随意,但是通常跟消息的某些特性相关联.一些合法的路由选择键 ...
- RabbitMQ入门_07_Fanout 与 Topic
A. 用广播的方式实现发布订阅 参考资料:https://www.rabbitmq.com/tutorials/tutorial-three-java.html Fanout 类型的 Exchange ...
- spring boot整合RabbitMQ(Topic模式)
1.Topic交换器介绍 Topic Exchange 转发消息主要是根据通配符. 在这种交换机下,队列和交换机的绑定会定义一种路由模式,那么,通配符就要在这种路由模式和路由键之间匹配后交换机才能转发 ...
- RabbitMQ指南之五:主题交换器(Topic Exchange)
在上一章中,我们完善了我们的日志系统,用direct交换器替换了fanout交换器,使得我们可以有选择性地接收消息.尽管如此,仍然还有限制:不能基于多个标准进行路由.在我们的日志系统中,我们可能不仅希 ...
随机推荐
- Windows和Linux系统如何退出python命令行
python命令行是新手学习python过程中必须要学的一个工具,下面我们来看一下怎么退出python命令行. 第一种方式: 使用python提供的exit()函数,linux平台和windows平台 ...
- 当Kubernets遇上阿里云 -之七层负载均衡(一).
我们知道Kubernetes的service只能实现基于4层的负载均衡,无法提供7层之上的许多特性,诸如基于URL的负载均衡,SSL支持,三方授权等等:Ingress可以实现七层负载均衡的许多功能,唯 ...
- 3.Airflow使用
1. airflow简介2. 相关概念2.1 服务进程2.1.1. web server2.1.2. scheduler2.1.3. worker2.1.4. celery flower2.2 相关概 ...
- 3. IP地址转换函数
一.字符串表示的IP地址需要被转化为整数(二进制数)方能使用 IPv4地址:点分十进制字符串 IPv6地址:十六进制字符串 有时(如记录日志),我们则要把整数(二进制数)表示的IP地址转化为可读的字符 ...
- 团队展示(I know)
一.队员姓名与学号 姓名 学号 组长 陈家权 031502107 赖晓连 031502118 ★ 雷晶 031502119 林巧娜 031502125 庄加鑫 031502147 二.队名 I kno ...
- 倒计时60s 代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 【第五周】四则运算GUI
这次这个简陋的程序终于发布了,其实发布很简单(在windows平台),因为使用的是vs2008+qt4.7的组合,在微软自家平台上用一用还是很方便的,只需要在release编译生成的exe文件,加上几 ...
- java结合testng,利用XML做数据源的数据驱动示例
testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本.在这以XML为例: 备注:@DataProvider的返回值 ...
- IPv4编址及子网划分
在讨论IP编址之前,我们需要讨论一下主机与路由器连入网络的方法.一台主机通常只有一条链路链接到网络:当主机中的IP想发送一个数据报时,它就在链路上发送,主机与物理链路之间的边界叫做接口(interfa ...
- VBA-从周课表统计节次
Sub datainsert() Dim r1 As Integer, r2 As Integer, i As Integer, j As Integer, findrow As Integer, f ...