实际上,我有两个关于主题交流的问题。
问题1:我认为只有队列和交换相互绑定是可以的,为什么生产者和交换需要绑定?
例如
# producer-->exchange--routing_key-->queues and customer
cat run.log |grep "routing_key_a" >> customer A;
cat run.log |grep "routing_key_b" >> customer B;
我将cat run.log
用作消息生产者,并将grep "routing_key_a"
用作routing_key,生产者产生了所有消息,并使用不同的routing_keys分发给了不同的客户A和B。这很容易理解,所以我不明白为什么我们仍然需要生产者和交换彼此绑定?
第二季度:我可以在生产者绑定中使用遗嘱卡进行交换(而不是在将遗嘱卡绑定至队列时使用遗留卡)吗?我曾经尝试过并且遇到了一些问题。
class RabbitmqServer:
def __init__(self, host, port, nick_name="", topics=None, log_data=None):
self.host = host
self.port = port
self.nick_name = nick_name
self.connection = self._build_connection()
self.channel = self._open_channel()
self.exchange = self._declare_exchange()
self.topics = topics if isinstance(topics, (list, tuple)) else [] # used to binding_key and routing_key
self.log_data = log_data if log_data else [] # used to create log
def _build_connection(self):
return pika.BlockingConnection(
pika.ConnectionParameters(host=self.host, port=self.port)
)
def _open_channel(self):
return self.connection.channel()
def _declare_exchange(self):
return self.channel.exchange_declare(exchange="radius_logs", exchange_type="topic")
下面是生产者代码。
class SimpleLogger(RabbitmqServer):
def __init__(self, *args, **kwargs):
super(SimpleLogger, self).__init__(*args, **kwargs)
def _publish(self, message):
i = 1
while True:
log_index = i % len(self.log_data)
log = self.log_data[log_index]
_message = json.dumps(f"[{log}] "
f"There is a piece log from radius server: {message}-No.-{i}")
for topic in self.topics:
self.channel.basic_publish(
exchange="radius_logs",
routing_key=topic,
body=_message
)
print(f"producer with message: {_message}")
i += 1
time.sleep(0.15)
def run(self):
try:
self._publish("1PMC")
except Exception as e:
print(f"Found exception: {e}")
print("Exit..")
self.connection.close()
下面是消费者。
class SimpleConsumer(RabbitmqServer):
def __init__(self, *args, **kwargs):
super(SimpleConsumer, self).__init__(*args, **kwargs)
def _call_back(self, ch, method, properties, body):
print(f"consumer with name = {self.nick_name} received {body}")
ch.basic_ack(delivery_tag=method.delivery_tag)
time.sleep(0.4)
def _consume(self):
queue = self.channel.queue_declare(queue="", exclusive=True)
queue_name = queue.method.queue
for t in self.topics:
self.channel.queue_bind(exchange="radius_logs", queue=queue_name, routing_key=t)
self.channel.basic_consume(on_message_callback=self._call_back, queue=queue_name, auto_ack=False)
self.channel.start_consuming()
def run(self):
try:
self._consume()
except Exception as e:
print(f"Found exception: {e}")
print("Exit..")
self.connection.close()
下面是运行代码。
if __name__ == "__main__":
r_host = "10.0.7.176"
r_port = 5672
p1_binding_keys = ["*.orange.*", ]
c1_binding_keys = ["*.orange.*", ]
c2_binding_keys = ["*.*.rabbit", "lazy.#"]
log_data = [
"quick.orange.rabbit", # will send to C1
"lazy.orange.elephant", # will send to C1
"quick.orange.fox", # will send to C1
"lazy.brown.fox", # will send to nobody
"lazy.pink.rabbit", # will send to nobody
"quick.brown.fox", # will send to nobody
"orange", # will send to nobody
"quick.orange.male.rabbit", # will send to nobody
"lazy.orange.male.rabbit", # will send to nobody
]
p1 = SimpleLogger(host=r_host, port=r_port, nick_name="P1", log_data=log_data, topics=p1_binding_keys)
c1 = SimpleConsumer(host=r_host, port=r_port, nick_name="C1", topics=c1_binding_keys)
c2 = SimpleConsumer(host=r_host, port=r_port, nick_name="C2", topics=c2_binding_keys)
t1 = threading.Thread(target=p1.run)
t2 = threading.Thread(target=c1.run)
t3 = threading.Thread(target=c2.run)
t1.start()
t2.start()
t3.start()
期望:log_data
是一个列表,用于创建日志内容,预期仅"quick.orange.rabbit", "lazy.orange.elephant", "lazy.brown.fox",
发送给使用者C1,其余的将丢失。
实际上: 没有消息发送到C2,这与我们的预期相同。
⚙ rabitmq_demo # grep -i "C2" 5.log
✘ ⚙ rabitmq_demo
但是,所有消息都发送到C1,这与预期的有所不同。为什么可以将诸如"quick.brown.fox",
之类的消息发送到C1?
正如Question1所说,我真的对生产者进行交换的binding_key感到困惑,我认为不需要绑定生产者进行交换,对吗?可以向我解释这一点的人,非常感谢。
rabitmq_demo # grep -i "C1" run.log
consumer with name = C1 received b'"[quick.orange.fox] There is a piece log from radius server: 1PMC-No.-2"'
consumer with name = C1 received b'"[lazy.brown.fox] There is a piece log from radius server: 1PMC-No.-3"'
consumer with name = C1 received b'"[lazy.pink.rabbit] There is a piece log from radius server: 1PMC-No.-4"'
consumer with name = C1 received b'"[quick.brown.fox] There is a piece log from radius server: 1PMC-No.-5"'
consumer with name = C1 received b'"[orange] There is a piece log from radius server: 1PMC-No.-6"'
consumer with name = C1 received b'"[quick.orange.male.rabbit] There is a piece log from radius server: 1PMC-No.-7"'
consumer with name = C1 received b'"[lazy.orange.male.rabbit] There is a piece log from radius server: 1PMC-No.-8"'
consumer with name = C1 received b'"[quick.orange.rabbit] There is a piece log from radius server: 1PMC-No.-9"'
consumer with name = C1 received b'"[lazy.orange.elephant] There is a piece log from radius server: 1PMC-No.-10"'
consumer with name = C1 received b'"[quick.orange.fox] There is a piece log from radius server: 1PMC-No.-11"'
consumer with name = C1 received b'"[lazy.brown.fox] There is a piece log from radius server: 1PMC-No.-12"'
consumer with name = C1 received b'"[lazy.pink.rabbit] There is a piece log from radius server: 1PMC-No.-13"'
consumer with name = C1 received b'"[quick.brown.fox] There is a piece log from radius server: 1PMC-No.-14"'
consumer with name = C1 received b'"[orange] There is a piece log from radius server: 1PMC-No.-15"'