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 已经 成功在远程服务器上部署 了!🚀
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号