Rabbitmq--topic

本文深入探讨了RabbitMQ中Topic Exchange的使用方法和模糊匹配规则,通过实例展示了如何在生产者和消费者之间利用模式匹配进行消息路由。
 

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 需要改一下

  生产端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# -*- 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()

  消费端:

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# -*- 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.*']

   生产者分别输入:   

1
2
3
4
5
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 的信息。

 
分类:  网络编程进阶
 
好文要顶  关注我  收藏该文   
 
 
+加关注
0
0
 
 
 
« 上一篇: Rabbitmq -- direct
» 下一篇: Rabbitmq -- rpc
posted @  2018-01-08 10:24 Bigberg 阅读(474) 评论(0) 编辑 收藏
 

转载于:https://www.cnblogs.com/leigepython/p/11015037.html

### RabbitMQTopic 模式的使用与配置 #### 1. 基本概念 在 RabbitMQTopic 模式下,消息路由键(routing key)和绑定键(binding key)都可以包含多个单词,这些单词之间用点号 `.` 分隔。生产者发送消息时指定一个路由键,而消费者则通过定义特定的绑定键来订阅感兴趣的消息类型。 #### 2. 生产者的实现方式 对于生产者而言,在发送消息到 Topic 类型的交换机时,只需要调用 `convertAndSend` 方法并传入相应的参数即可。例如: ```java @Autowired private RabbitTemplate rabbitTemplate; public void sendMsg() { String exchangeName = "topicExchange"; String routingKey = "key1"; // 路由键应遵循一定的命名规则以便于匹配 Object messageBody = "This is a test message."; rabbitTemplate.convertAndSend(exchangeName, routingKey, messageBody); } ``` 此段代码展示了如何利用 Spring AMQP 提供的 `RabbitTemplate` 来向名为 `"topicExchange"` 的 Topic Exchange 发送一条带有自定义路由键的消息[^2]。 #### 3. 绑定关系设置 为了使消费者能够接收到符合条件的消息,需建立合适的绑定关系。这通常是在声明队列之后完成的操作,即先创建好队列再将其与某个 Topic Exchange 关联起来,并指明具体的 binding key 形式。比如下面的例子说明了一个简单的绑定过程: ```java // 定义队列名称以及对应的 Binding Key 表达式 String queueName = "testQueue"; String pattern = "*.orange.*"; // 执行绑定操作 amqpAdmin.declareBinding(BindingBuilder.bind(new Queue(queueName)) .to(new DirectExchange("topicExchange")) .with(pattern)); ``` 这里使用的 `pattern` 参数支持通配符语法,其中星号(*)代表任意单个词,井号(#)表示零个或多个词语[^4]。 #### 4. 实际应用场景中的注意事项 当实际应用中涉及到复杂的业务逻辑时,建议合理规划路由键的设计原则,确保其既具有足够的表达力又不会过于复杂难以维护;同时也要注意性能方面的影响因素,如过多的队列可能会导致资源消耗增加等问题[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值