68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
import asyncio
|
||
import aio_pika
|
||
from config import RABBITMQ_URI
|
||
|
||
|
||
async def queue_consumer(queue_name: str, consumer_id: int):
|
||
"""
|
||
单个队列的消费者
|
||
:param queue_name: 要监听的队列名称
|
||
:param consumer_id: 消费者ID,用于区分不同实例
|
||
"""
|
||
# 建立连接
|
||
connection = await aio_pika.connect_robust(RABBITMQ_URI)
|
||
channel = await connection.channel()
|
||
|
||
# 开启公平调度,确保消息均匀分配
|
||
# 消费者处理完一条消息后才会接收下一条
|
||
await channel.set_qos(prefetch_count=1)
|
||
|
||
# 声明要监听的队列(与生产者中创建的队列对应)
|
||
queue = await channel.declare_queue(
|
||
queue_name,
|
||
durable=True,
|
||
auto_delete=False
|
||
)
|
||
|
||
# 消息处理函数
|
||
async def on_message(message: aio_pika.IncomingMessage):
|
||
# 自动确认消息(处理完成后从队列中删除)
|
||
async with message.process():
|
||
content = message.body.decode("utf-8")
|
||
print(f"[Consumer {consumer_id}] Processing message: {content}")
|
||
print(f"[Consumer {consumer_id}] From queue: {queue_name}")
|
||
print(f"[Consumer {consumer_id}] Routing key: {message.routing_key}\n")
|
||
|
||
# 模拟业务处理耗时(根据实际场景调整)
|
||
await asyncio.sleep(1)
|
||
|
||
# 开始消费队列消息
|
||
consumer_tag = f"multi_consumer_{consumer_id}_{queue_name}"
|
||
await queue.consume(on_message, consumer_tag=consumer_tag)
|
||
print(f"[Consumer {consumer_id}] Started, listening to queue: {queue_name} (tag: {consumer_tag})")
|
||
|
||
# 保持消费者运行(无限期阻塞)
|
||
await asyncio.Future()
|
||
|
||
|
||
async def start_balanced_consumers(
|
||
queue_prefix="task.queue.",
|
||
queue_count=3
|
||
):
|
||
"""启动多个消费者,每个消费者对应一个队列"""
|
||
# 创建消费者任务列表
|
||
consumer_tasks = []
|
||
for i in range(queue_count):
|
||
queue_name = f"{queue_prefix}{i + 1}"
|
||
# 每个队列对应一个独立的消费者
|
||
task = asyncio.create_task(queue_consumer(queue_name, i + 1))
|
||
consumer_tasks.append(task)
|
||
|
||
# 同时运行所有消费者
|
||
await asyncio.gather(*consumer_tasks)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
# 启动3个消费者,分别对应3个队列
|
||
asyncio.run(start_balanced_consumers(queue_count=3))
|