Python操作RabbitMQ

一、基本使用

  1. 使用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
  1. 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. 如果消费者意外崩溃,如何自动重启?

可以使用 SupervisorDocker restart policysystemd 监控 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 已经 成功在远程服务器上部署 了!🚀

posted on   朝朝暮Mu  阅读(14)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示