ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

RabbitMQ主题交换机

2021-06-29 03:00:17  阅读:159  来源: 互联网

标签:单词 name exchange 主题 RabbitMQ queue 交换机 路由 channel


之前的教程里,我们只改进了我们的日志系统,我们使用直连交换机替代了扇形交换机,从只能盲目的广播消息改进为有可能选择性的接收日志

尽管直连交换机能够改善我们的系统,但是它也有它的限制--没办法基于多个标准执行路由操作

在我们的日志系统中,我们不只希望订阅基于严重程度的日志,同时还希望订阅基于发送来源的日志。Unix根据syslog就是基于严重程度-severity(info/warn/crit...)和设备-facility(auth/cron/kern...)来路由日志的

 

主题交换机

发送到主题交换机(topic exchange)的消息不可以携带随意什么样子的路由器(routing key), 它的路由键是由一个.分隔开的词语列表。 这些单词随意是什么样的都可以。但最好是携带和它们消息有关系的词汇。比如: stock.usd.nyse等, 词语的个数可以随意,但是不要超过255字节。

绑定键也必须拥有同样的格式。主题交换机背后的逻辑跟直连交换机很相似--一个携带着特定路由键的消息会被主题交换机投递给绑定键与之相匹配的队列。但是它的绑定键和路由键有两个特殊的应用方式:

* (星号) 用来表示一个单词

# (井号) 用来表示任意数量(零个或者多个)单词

 

 

 在这个例子中,我们发送的所有消息都是用来描述小动物的。发送的消息携带的路由键是由三个单词所组成的。这三个单词被两个.分隔开。路由键的第一个单词描述的是动物手脚的利索程度,第二个单词是动物的颜色,第三个是动物的种类。所以它看起来是这样的: <celerity>.<color>.<species>

我们创建了三个绑定: Q1的绑定键为*.orange.*, Q2的绑定键为*.*rabbit和lazy.#

这三个绑定键可以被总结为:

Q1对所有的橘黄色动物都感兴趣

Q2则是对所有的兔子和所有懒惰的动物感兴趣

 

代码整合

生产者:

#!/usr/bin/env python
import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

exchange_name = 'logs4'
channel.exchange_declare(exchange=exchange_name, exchange_type='topic')

message = (' '.join(sys.argv[1:]) or "info: Hello World!")
channel.basic_publish(exchange=exchange_name,
                      routing_key='lazy.green.rabbit',
                      body=message)
print(" [x] Sent %r" % (message,))
connection.close()

 

消费者1:

#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(
    host='localhost'))
channel = connection.channel()

exchange_name = 'logs4'
channel.exchange_declare(exchange=exchange_name,
                         exchange_type='topic')

queue_name = 'test1'
result = channel.queue_declare(queue=queue_name, exclusive=True)
# queue_name = result.method.queue

channel.queue_bind(exchange=exchange_name,
                   queue=queue_name,
                   routing_key='lazy.*.dog')  # * 表示的是一个单词, # 任意数量(0或者多个单词)

print(' [*] Waiting for logs. To exit press CTRL+C')


def callback(ch, method, properties, body):
    print(" [x] %r" % (body,))


channel.basic_consume(queue=queue_name,
                      on_message_callback=callback,
                      exclusive=True,
                      auto_ack=False)  # 在用完此队列后立即删除

channel.start_consuming()

 

消费者2:

#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(
    host='localhost'))
channel = connection.channel()

exchange_name = 'logs4'
channel.exchange_declare(exchange=exchange_name,
                         exchange_type='topic')

queue_name = 'test2'
result = channel.queue_declare(queue=queue_name, exclusive=True)

channel.queue_bind(exchange=exchange_name,
                   queue=queue_name,
                   routing_key='*.*.rabbit')  # 只接收到尾号为rabbit路由键的消息

print(' [*] Waiting for logs. To exit press CTRL+C')


def callback(ch, method, properties, body):
    print(" [x] %r" % (body,))


channel.basic_consume(queue=queue_name,
                      on_message_callback=callback,
                      exclusive=True,
                      auto_ack=False)  # 在用完此队列后立即删除

channel.start_consuming()

 

1. 绑定键为*的队列会取到一个路由键为空的消息吗?

不能, * 表示至少有一个单词, 路由键为空的是无法接收到的

2. 绑定键为#.*的队列会获取到一个名为..的路由键的消息吗? 它会取到一个路由键为单个单词的消息吗?

会的,绑定键为#可以是任意0或者多个, * 至少为一个单词,所有#.*可以获取到名为..路由键的消息。

3. a.*.#和a.#的区别在哪里?

a.*.#中间的*至少要有一个单词,也就是说第一个至少需要两个单词匹配,a和*。而a.#只需要a这个单词匹配成功即可。

 

标签:单词,name,exchange,主题,RabbitMQ,queue,交换机,路由,channel
来源: https://www.cnblogs.com/yunxintryyoubest/p/14948213.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有