Python操作RabbitMQ
一、基本使用
- 使用Homebrew安装RabbitMQ
# 更新 homebrew brew update # 安装 brew install rabbitmq # 查看安装位置 brew info rabbitmq # 启动 brew services start rabbitmq # 启动配置 /opt/homebrew/sbin/rabbitmqctl enable_feature_flag all # 停止服务 brew services stop rabbitmq # 或者 /opt/homebrew/sbin/rabbitmqctl shutdown
- Python操作RabbitMQ
# 安装依赖 pip install pika
二、集成FastAPI-简单队列
在 FastAPI 中集成 RabbitMQ,通常使用 pika 或 aio_pika 库来处理消息队列。aio_pika 是异步的,更适合 FastAPI 的异步特性。
1. 安装依赖:
pip install fastapi uvicorn aio_pika
2. 启动 RabbitMQ:
如果尚未安装 RabbitMQ,可以使用 Docker 运行:
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management
RabbitMQ 默认管理面板:http://localhost:15672(用户名/密码:guest/guest)
3. 生产者(Producer)示例:
创建 producer.py 发送消息到 RabbitMQ 队列:
import asyncio import aio_pika RABBITMQ_URL = "amqp://guest:guest@localhost/" async def send_message(queue_name: str, message: str): connection = await aio_pika.connect_robust(RABBITMQ_URL) async with connection: channel = await connection.channel() await channel.default_exchange.publish( aio_pika.Message(body=message.encode()), routing_key=queue_name, ) print(f"Sent: {message}") # 示例调用 if __name__ == "__main__": asyncio.run(send_message("task_queue", "Hello, RabbitMQ!"))
4. 消费者(Consumer)示例:
创建 consumer.py 监听 RabbitMQ 消息:
import asyncio import aio_pika RABBITMQ_URL = "amqp://guest:guest@localhost/" async def consume(queue_name: str): connection = await aio_pika.connect_robust(RABBITMQ_URL) async with connection: channel = await connection.channel() queue = await channel.declare_queue(queue_name) async for message in queue: async with message.process(): print(f"Received: {message.body.decode()}") if __name__ == "__main__": asyncio.run(consume("task_queue"))
5. 在 FastAPI 中使用 RabbitMQ:
创建 main.py,并在 FastAPI 端点中发送消息:
from fastapi import FastAPI, BackgroundTasks import asyncio from producer import send_message app = FastAPI() @app.get("/send/{message}") async def send_message_to_queue(message: str, background_tasks: BackgroundTasks): background_tasks.add_task(send_message, "task_queue", message) return {"message": f"Message '{message}' sent to queue."}
6. 运行 FastAPI 和测试:
启动 FastAPI:
uvicorn main:app --reload
然后在浏览器访问:
http://127.0.0.1:8000/send/hello
这将向 RabbitMQ 发送 "hello" 消息。
启动消费者:
python consumer.py
如果成功,消费者会输出:
Received: hello
总结:
1. aio_pika 处理 RabbitMQ 连接(异步支持)。
2. 生产者(FastAPI) 在 API 请求时发送消息到队列。
3. 消费者(独立进程) 监听队列并处理消息。
这样 FastAPI 和 RabbitMQ 就顺利集成了!🚀
三、使用主题
在 FastAPI 中使用 RabbitMQ Topic Exchange,可以通过 aio_pika 实现 主题模式(Topic Exchange),允许消息按主题进行路由。
1. 理解 Topic Exchange
在 RabbitMQ 的 Topic Exchange 中:
• 生产者 发送消息到 交换机(Exchange),并指定 routing key。
• 队列(Queue) 绑定到 交换机,并使用 绑定键(Binding Key) 进行匹配:
• logs.error 匹配 logs.*
• logs.error.system 匹配 logs.#
• logs.info 不匹配 logs.error.#
2. 安装 RabbitMQ 并启动
如果尚未安装 RabbitMQ,可以用 Docker 运行:
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management
RabbitMQ 管理面板:http://localhost:15672(用户名/密码:guest/guest)
3. 生产者(Producer)发送带 Topic 的消息
创建 producer.py,用于向 RabbitMQ 发送 Topic 消息:
import asyncio import aio_pika RABBITMQ_URL = "amqp://guest:guest@localhost/" EXCHANGE_NAME = "topic_logs" async def send_message(routing_key: str, message: str): connection = await aio_pika.connect_robust(RABBITMQ_URL) async with connection: channel = await connection.channel() # 声明 Topic Exchange exchange = await channel.declare_exchange(EXCHANGE_NAME, aio_pika.ExchangeType.TOPIC) # 发送消息 await exchange.publish( aio_pika.Message(body=message.encode()), routing_key=routing_key ) print(f"Sent [{routing_key}]: {message}") # 示例调用 if __name__ == "__main__": asyncio.run(send_message("logs.info", "This is an info log.")) asyncio.run(send_message("logs.error.system", "System error detected!"))
4. 消费者(Consumer)监听 Topic
创建 consumer.py,监听特定 Topic 的消息:
import asyncio import aio_pika RABBITMQ_URL = "amqp://guest:guest@localhost/" EXCHANGE_NAME = "topic_logs" async def consume(binding_keys: list): connection = await aio_pika.connect_robust(RABBITMQ_URL) async with connection: channel = await connection.channel() # 声明 Topic Exchange exchange = await channel.declare_exchange(EXCHANGE_NAME, aio_pika.ExchangeType.TOPIC) # 创建临时队列(auto_delete=True) queue = await channel.declare_queue("", exclusive=True) # 绑定队列到 Exchange,使用多个 binding_keys for key in binding_keys: await queue.bind(exchange, routing_key=key) print(f"[*] Waiting for messages with binding keys: {binding_keys}") async for message in queue: async with message.process(): print(f"Received [{message.routing_key}]: {message.body.decode()}") if __name__ == "__main__": binding_keys = ["logs.error.#"] # 监听所有 "logs.error.*" 级别日志 asyncio.run(consume(binding_keys))
5. FastAPI 端点,发送 Topic 消息
创建 main.py,在 FastAPI 端点中发送 Topic 消息:
from fastapi import FastAPI, BackgroundTasks import asyncio from producer import send_message app = FastAPI() @app.get("/send/{routing_key}/{message}") async def send_message_to_topic(routing_key: str, message: str, background_tasks: BackgroundTasks): background_tasks.add_task(send_message, routing_key, message) return {"message": f"Sent [{routing_key}]: {message}"}
6. 运行 FastAPI 和测试
启动 FastAPI:
uvicorn main:app --reload
然后在浏览器或 Postman 访问:
http://127.0.0.1:8000/send/logs.error/system_error_detected
这将发送 "system_error_detected" 到 "logs.error" 主题。
启动消费者:
python consumer.py
如果 consumer.py 监听的是 "logs.error.#",它会接收到:
Received [logs.error.system]: system_error_detected
7. 总结
1. Topic Exchange 允许按主题(routing_key)分类消息。
2. 生产者 发送消息到 topic_logs 交换机,并指定 routing_key。
3. 消费者 绑定 routing_key 进行消息过滤,如 "logs.error.#" 监听所有 "logs.error.*" 消息。
4. FastAPI 提供 API 端点,支持 RabbitMQ Topic 发送消息。
🚀 这样 FastAPI 就可以通过 RabbitMQ 实现 主题模式(Topic Exchange) 了!
四、注意事项
1. 消费者如何保持监听
在 consumer.py 中,我们使用了 async for message in queue 语句:
async for message in queue: async with message.process(): print(f"Received [{message.routing_key}]: {message.body.decode()}")
这个循环会:
• 自动阻塞,等待 RabbitMQ 队列中有新的消息。
• 当 有新消息到达 时,触发 message.process() 进行消费。
• 如果没有消息,消费者会一直等待,不会主动退出。
2. 如果 RabbitMQ 服务器重启,消费者会断开吗?
是的,如果 RabbitMQ 服务器重启,连接会丢失,但我们可以使用 aio_pika.connect_robust() 让消费者 自动重连:
connection = await aio_pika.connect_robust(RABBITMQ_URL)
这样,当 RabbitMQ 重启时,消费者会 自动尝试重新连接,无需手动干预。
3. 如何优雅地关闭消费者?
在 FastAPI 或独立 consumer.py 运行时,可以捕获 KeyboardInterrupt,优雅地关闭连接:
import asyncio import aio_pika RABBITMQ_URL = "amqp://guest:guest@localhost/" EXCHANGE_NAME = "topic_logs" async def consume(binding_keys: list): connection = await aio_pika.connect_robust(RABBITMQ_URL) async with connection: channel = await connection.channel() exchange = await channel.declare_exchange(EXCHANGE_NAME, aio_pika.ExchangeType.TOPIC) queue = await channel.declare_queue("", exclusive=True) for key in binding_keys: await queue.bind(exchange, routing_key=key) print(f"[*] Waiting for messages with binding keys: {binding_keys}") try: async for message in queue: async with message.process(): print(f"Received [{message.routing_key}]: {message.body.decode()}") except asyncio.CancelledError: print("Consumer task cancelled, closing connection...") if __name__ == "__main__": loop = asyncio.get_event_loop() task = loop.create_task(consume(["logs.error.#"])) try: loop.run_forever() # 让消费者持续运行 except KeyboardInterrupt: print("Shutting down consumer...") task.cancel() loop.run_until_complete(task)
改进点:
• try-except asyncio.CancelledError 处理 任务取消 时的清理工作。
• loop.run_forever() 让消费者始终运行,直到 Ctrl + C 退出。
• task.cancel() 关闭消费者,防止不干净退出。
4. 如果消费者意外崩溃,如何自动重启?
可以使用 Supervisor、Docker restart policy 或 systemd 监控 consumer.py,确保它始终运行。
使用 Supervisor 监控
安装 supervisor:
sudo apt install supervisor
添加 /etc/supervisor/conf.d/rabbitmq_consumer.conf:
[program:rabbitmq_consumer] command=python3 /path/to/consumer.py autostart=true autorestart=true stderr_logfile=/var/log/rabbitmq_consumer.err.log stdout_logfile=/var/log/rabbitmq_consumer.out.log
然后重新加载 supervisor:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start rabbitmq_consumer
使用 Docker 自动重启
如果消费者运行在 Docker 容器中,可以添加 --restart=always:
docker run -d --restart=always my-consumer-image
5. 总结
✅ 消费者会持续监听,不会主动退出。
✅ 使用 aio_pika.connect_robust() 防止连接丢失(支持 RabbitMQ 重启自动重连)。
✅ 通过 捕获 KeyboardInterrupt 实现 优雅关闭。
✅ 生产环境中可以使用 Supervisor、Docker 或 systemd 保证消费者 自动重启。
这样,你的 FastAPI + RabbitMQ 消费者就可以 稳定地监听 消息队列了!🚀
五、远程调用
在远程云服务器上部署 RabbitMQ 并调用 FastAPI,可以按照以下步骤进行:
1. 在云服务器上安装 RabbitMQ
可以在 Ubuntu/Debian 服务器上使用 apt 安装 RabbitMQ。
步骤 1.1 安装 RabbitMQ
SSH 登录远程服务器后,运行:
sudo apt update sudo apt install rabbitmq-server -y
安装完成后,启动 RabbitMQ:
sudo systemctl enable rabbitmq-server sudo systemctl start rabbitmq-server
检查 RabbitMQ 状态:
sudo systemctl status rabbitmq-server
步骤 1.2 启用 RabbitMQ Web 管理界面
sudo rabbitmq-plugins enable rabbitmq_management
然后,开放 Web 端口:
sudo ufw allow 15672/tcp
访问管理面板:
http://your-server-ip:15672
默认账户:
• 用户名:guest
• 密码:guest
(注意:guest 用户默认只允许本地访问,建议创建新用户)
步骤 1.3 创建远程访问用户
创建一个新用户:
sudo rabbitmqctl add_user admin password123
赋予管理员权限:
sudo rabbitmqctl set_user_tags admin administrator sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
2. 配置 RabbitMQ 允许远程访问
默认情况下,RabbitMQ 只允许本地访问 5672 端口。要开放远程访问,执行以下步骤。
步骤 2.1 修改 RabbitMQ 配置
编辑配置文件:
sudo nano /etc/rabbitmq/rabbitmq.conf
添加:
listeners.tcp.default = 5672
保存后重启:
sudo systemctl restart rabbitmq-server
步骤 2.2 开放 RabbitMQ 端口
sudo ufw allow 5672/tcp
如果使用 AWS、GCP 或阿里云,需要在云控制台 安全组 开启 5672 端口。
3. 在本地 FastAPI 生产者调用远程 RabbitMQ
在本地 FastAPI 服务器中,安装 aio_pika:
pip install fastapi uvicorn aio_pika
修改 producer.py,连接 远程服务器:
import asyncio import aio_pika RABBITMQ_URL = "amqp://admin:password123@your-server-ip/" async def send_message(queue_name: str, message: str): connection = await aio_pika.connect_robust(RABBITMQ_URL) async with connection: channel = await connection.channel() await channel.default_exchange.publish( aio_pika.Message(body=message.encode()), routing_key=queue_name, ) print(f"Sent: {message}") # 示例调用 if __name__ == "__main__": asyncio.run(send_message("task_queue", "Hello from local machine!"))
📌 确保替换 your-server-ip 为你的云服务器 IP。
4. 在远程服务器上运行消费者
步骤 4.1 复制 consumer.py 到云服务器
创建 consumer.py:
import asyncio import aio_pika RABBITMQ_URL = "amqp://admin:password123@localhost/" async def consume(queue_name: str): connection = await aio_pika.connect_robust(RABBITMQ_URL) async with connection: channel = await connection.channel() queue = await channel.declare_queue(queue_name) async for message in queue: async with message.process(): print(f"Received: {message.body.decode()}") if __name__ == "__main__": asyncio.run(consume("task_queue"))
步骤 4.2 启动消费者
python3 consumer.py
然后,在本地 FastAPI 调用 /send/your_message,消费者应该会收到消息。
5. 在 FastAPI 中调用远程 RabbitMQ
在 FastAPI 中集成 RabbitMQ:
from fastapi import FastAPI, BackgroundTasks import asyncio from producer import send_message app = FastAPI() @app.get("/send/{message}") async def send_message_to_queue(message: str, background_tasks: BackgroundTasks): background_tasks.add_task(send_message, "task_queue", message) return {"message": f"Message '{message}' sent to queue."}
步骤 5.1 运行 FastAPI
在本地运行:
uvicorn main:app --reload
然后访问:
http://127.0.0.1:8000/send/hello
消费者 端应该会收到:
Received: hello
6. 生产环境优化
6.1 使用 Supervisor 保持消费者运行
在云服务器上安装 supervisor:
sudo apt install supervisor -y
创建 /etc/supervisor/conf.d/rabbitmq_consumer.conf:
[program:rabbitmq_consumer] command=python3 /path/to/consumer.py autostart=true autorestart=true stderr_logfile=/var/log/rabbitmq_consumer.err.log stdout_logfile=/var/log/rabbitmq_consumer.out.log
启动 supervisor:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start rabbitmq_consumer
这样即使 consumer.py 崩溃,也会自动重启。
7. 总结
✅ 在远程云服务器上安装 RabbitMQ。
✅ 配置 RabbitMQ 允许远程访问(5672 端口)。
✅ 创建 RabbitMQ 用户并赋权。
✅ 在本地 FastAPI 生产者调用远程 RabbitMQ。
✅ 在云服务器上运行 RabbitMQ 消费者。
✅ 使用 Supervisor 让 RabbitMQ 消费者长期运行。
这样,你的 FastAPI + RabbitMQ 已经 成功在远程服务器上部署 了!🚀
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人