我是新手处理消息交换并遇到问题,找到适合该任务的手册。
我需要组织一系列队列,以便:
生产者创建一些随机空队列并在那里写下所有消息包(通常是100条消息)。
消费者找到非空和非锁定队列并从中读取,直到 它是空的然后删除它并寻找下一个。
所以我的任务是使用消息作为包,我理解如何在一个队列中使用相同的密钥生成和使用,但无法找到如何使用队列池。
我们可以让几个生产者和消费者并行运行,但不管他们中的哪一个发送给谁。 我们不需要也无法将特定生产者与特定消费者联系起来。
一般任务:我们有很多客户端接收推送通知,我们将一些参数分组推送到以后作为组处理,所以这样的组应该在RabbitMQ中的一个队列中生成并且作为一个群体消费,但每个群体独立于其他群体。
非常感谢Hannu的帮助:他简单而强大的解决方案的关键理念,我们可以拥有一个具有已知名称的持久队列,其中生产者将写入已创建队列的名称,消费者将读取这些名称从那里。
为了使他的解决方案更具可读性和易用性以后在我的个人任务中,我将生产者中的publish_data()分成两个函数 - 一个制作随机队列并将其写入control_queue另一个接收这个random_queue并用消息填充它。类似的想法对于消费者来说是好的 - 一个处理队列的功能,另一个将被称为处理消息本身。
答案 0 :(得分:1)
我做过类似的事,但是和Pika一起。我不得不为这些例子清理和制作旧的代码片段。它可能不是非常kombuish(这是我绝对使用它编写的第一个代码片段)但这就是我将如何解决它。基本上我会设置一个具有已知名称的控制队列。
发布者将为一包邮件创建随机队列名称,向其转储N条消息(在我的情况下为1-42),然后将队列名称发布到控制队列。然后,使用者接收此队列名称,绑定它,读取消息直到队列为空,然后删除队列。
这使事情变得相对简单,因为发布者不需要弄清楚他们在哪里发布他们的数据组(每个队列都是随机名称的新队列)。接收方不需要担心超时或“全部完成”消息,因为只有当一组数据已写入队列且每条消息都在等待时,接收方才会收到队列名称。
也没有必要修补锁或信号或其他任何会使事情复杂化的事情。您可以拥有任意数量的消费者和生产者。当然,使用交换和路由密钥可能会有不同的消费者群体用于不同的任务等。
<强>发布商强>
from kombu import Connection
import uuid
from time import sleep
def publish_data(conn):
random_name= "q" + str(uuid.uuid4()).replace("-", "")
random_queue = conn.SimpleQueue(random_name)
for i in xrange(0, 42):
random_queue.put(i)
random_queue.close()
return random_name
with Connection('amqp://guest:guest@localhost:5672//') as conn:
control_queue = conn.SimpleQueue('control_queue')
_a = 0
while True:
y_name = publish_data(conn)
message = y_name
control_queue.put(message)
print('Sent: {0}'.format(message))
_a += 1
sleep(0.3)
if _a > 20:
break
control_queue.close()
<强>消费强>
from Queue import Empty
from kombu import Connection, Queue
def process_msg(foo):
print str(foo)
with Connection("amqp://guest:guest@localhost:5672//") as _conn:
sub_queue = _conn.SimpleQueue(str(foo))
while True:
try:
_msg = sub_queue.get(block=False)
print _msg.payload
_msg.ack()
except Empty:
break
sub_queue.close()
chan = _conn.channel()
dq = Queue(name=str(foo), exchange="")
bdq = dq(chan)
bdq.delete()
with Connection('amqp://guest:guest@localhost:5672//') as conn:
rec = conn.SimpleQueue('control_queue')
while True:
msg = rec.get(block=True)
entry = msg.payload
msg.ack()
process_msg(entry)