Python 操作 Rabbit MQ 主题交换机 (七)

Python 操作 Rabbit MQ 主题交换机 (七)

一、主题交换机(Topic Exchange):

主题交换机的消息不可以携带随意的路由键(routing_key),它的路由键必须是一个由.分隔开的词语列表。

  • 建议:这些单词最好跟携带它们的消息有关系的词汇。比如:“quick.orange.rabbit”。
  • 注意:词语的个数可以随意,但是不要超过255字节。

绑定键也必须拥有同样的格式。主题交换机跟直连交换机比较相似,一个携带着特定路由键的消息会被主题交换机投递给绑定键与想匹配的队列

绑定键跟路由键两个特殊应用方式:

  • *星号:用来表示一个单词;
  • #井号:用来表示任意数量(零个或者多个)单词;

图解:

img

详解:

发送的消息所携带的路由键是由三个单词组成,这三个单词被两个.分割开。

图中创建了三个绑定:Q1的绑定键为:*.orange.*,Q2的绑定键为:*. *. rabbitlazy.#

绑定键可总结为:

  • Q1对所有桔黄色的事物都感兴趣;
  • Q2对所有兔子和所有懒惰的事物感兴趣;

举栗子

携带着有quick.orange.rabbit的消息会被分别投递给两个队列中。

  • Q1与Q2队列;

携带着lazy.orange.elephant的消息也会被分别投递给两个队列中。

  • Q1与Q2队列;

携带着quick.orange.fox的消息仅会投递一个队列中。

  • Q1队列;

携带着lazy.brown.fox的消息会投递给一个队列中。

  • Q2队列;

携带着lazy.pink.rabbit的消息仅会投递给一个队列中。

  • Q2队列;

携带着quick.brown.fox的消息不会投递给任何一个队列中。

如果违反约定,发送一个携带有一个单词或者四个单词(orange 或者 quick.orange.male.rabbit)的消息,发送消息不会投递给任何一个队列,而且会丢失掉。

  • lazy.orange.male.rabbit有四个单词,不过它不会丢失,因为lazy.#,#可匹配多个,会被投递到Q2队列中;

如果我们违反约定,发送了一个携带有一个单词或者四个单词("orange" or "quick.orange.male.rabbit")的消息时,发送的消息不会投递给任何一个队列,而且会丢失掉。

但是另一方面,即使 "lazy.orange.male.rabbit" 有四个单词,他还是会匹配最后一个绑定,并且被投递到第二个队列中。

简单总结:

1.当一个队列的绑定键为#(井号)的时候,这个队列将会无视消息的路由键,接收所有的消息。

2.当*(星号)和#(井号)这两个特殊字符都未在绑定键中出现,就可以理解`主题交换机就有用直连交换机的行为。

二、整合代码:

1.send.py的代码:

#!/usr/bin/python
# -*- coding: utf-8 -*- 
import pika
import sys

routing_key = sys.argv[1] if len(sys.argv) > 1 else 'anonymous.info'
message = ' '.join(sys.argv[2:]) or "Hello World!"

# 创建一个实例  本地访问IP地址可以为 localhost 后面5672是端口地址(>以不用指定, 因为默认就是5672)
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost', 5672))

# 声明一个管道, 在管道里发送消息
channel = connection.channel()

# 指定交换机名称:topic_logs 类型为:主题交换机
channel.exchange_declare(exchange='topic_logs', exchange_type='topic')

# 投递消息, 路由键
channel.basic_publish(exchange='topic_logs',
                      routing_key=routing_key,
                      body=message
                      )

print "[x] sent {}--{}".format(routing_key, message)
# 队列关闭
connection.close()

2.receive.py的代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import pika
import sys

# 创建实例
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))

# 声明管道
channel = connection.channel()

# 指定交换机名: topic_logs, 交换机的类型: 主题交换机
channel.exchange_declare(exchange='topic_logs', exchange_type='topic')

# 表示与消费者断开连接, 队列立即删除
result = channel.queue_declare(queue='', exclusive=True)

# 生成队列的名字
queue_name = result.method.queue

binding_keys = sys.argv[1:]
if not binding_keys:
    print >> sys.stderr, "Usage: %s [binding_key]....." % \
                         (sys.argv[0],)
    sys.exit(1)

for binding_key in binding_keys:
    # 绑定交换机和队列  这里注意的是绑定键, 就是根据按照指定严重级别>进行记录日志
    channel.queue_bind(exchange='topic_logs', queue=queue_name, routing_key=binding_key)


def callback(ch, method, properties, body):
    print '[X] Received{}'.format(body,)

# 消费消息
channel.basic_consume(queue=queue_name,  # 从指定的消息队列中接收消息
                      on_message_callback=callback,  # 如果收到消息, 就调用callback函数来处理
                        )

print('=======正在等待消息========')
channel.start_consuming()  # 开始消费消息

3.打开一个新的终端,执行下面命令,接收所有日志

python receive.py "#"
=======正在等待消息========

4.打开一个新的终端,执行下面命令,接收Django的日志:

python receive.py "Django.*"
=======正在等待消息========

5.打开一个新的终端,执行下面命令,接收以py结尾的日志:

python receive.py "*.py"
=======正在等待消息========

6.在打开一个新的终端,执行下面命令,建立多个绑定以Django开头或者js结尾的日志:

python receive.py "Django.*" "*.js"
=======正在等待消息========

7.打开新的终端,执行下面命令,发送路由键为Django.py的日志:

python send.py "Django.py" "send new message"

[x] sent Django.py--send new message

可以看到:以上的receive.py 文件都接收到了发出的消息:

=======正在等待消息 ========

[X] Receivedsend new message

如果执行:python send.py “fe_cow” “send error message”

可以看到,只有步骤3的队列才会处理消息:

=======正在等待消息 ========

[X] Receivedsend new message

[X] Receivedsend error message

三、查看当前队列信息:

1.查看当前已经绑定的队列列表:

rabbitmqctl list_bindings

Listing bindings ...
	exchange	amq.gen-A7-oPxJxMNdJFKp4rBLpRQ	queue	amq.gen-A7-oPxJxMNdJFKp4rBLpRQ	[]
	exchange	amq.gen-PxSynZTpkebC52Wyl7P7ag	queue	amq.gen-PxSynZTpkebC52Wyl7P7ag	[]
	exchange	amq.gen-hWwged-kY3-tzlWLY10K7g	queue	amq.gen-hWwged-kY3-tzlWLY10K7g	[]
	exchange	amq.gen-rVmLKIawWUNBQgJRQCv1ng	queue	amq.gen-rVmLKIawWUNBQgJRQCv1ng	[]
	exchange	hello	queue	hello	[]
	exchange	task_queue	queue	task_queue	[]
topic_logs	exchange	amq.gen-PxSynZTpkebC52Wyl7P7ag	queue	#	[]
topic_logs	exchange	amq.gen-rVmLKIawWUNBQgJRQCv1ng	queue	*.js	[]
topic_logs	exchange	amq.gen-A7-oPxJxMNdJFKp4rBLpRQ	queue	*.py	[]
topic_logs	exchange	amq.gen-hWwged-kY3-tzlWLY10K7g	queue	Django.*	[]
topic_logs	exchange	amq.gen-rVmLKIawWUNBQgJRQCv1ng	queue	Django.*	[]

交换机名:topic_logs 共绑定了5个队列。

2.查看当前交换器列表:

[root@iz2zeap40j01vg100ifsf4z /]# rabbitmqctl list_exchanges
Listing exchanges ...
amq.rabbitmq.log	topic
amq.direct	direct
amq.topic	topic
amq.headers	headers
direct_logs	direct
fanout_logs	fanout
	direct
amq.fanout	fanout
amq.rabbitmq.trace	topic
topic_logs	topic  # 交换机名:topic_logs  类型为:主题交换机
amq.match	headers

3.查看当前队列中的消息:

[root@iz2zeap40j01vg100ifsf4z /]# rabbitmqctl list_queues
Listing queues ...
hello	0
amq.gen-PxSynZTpkebC52Wyl7P7ag	2
amq.gen-A7-oPxJxMNdJFKp4rBLpRQ	1
amq.gen-rVmLKIawWUNBQgJRQCv1ng	1
task_queue	0
amq.gen-hWwged-kY3-tzlWLY10K7g	1
发布了147 篇原创文章 · 获赞 170 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/Fe_cow/article/details/101074049