《10 分钟上手 RabbitMQ:用 Python 写一个“不丢消息”的迷你消息系统》

标签:

RabbitMQ · Python · 消息队列 · 实战 Demo · 入门


为什么写这篇?

消息队列(MQ)的概念大家背得滚瓜烂熟:解耦、异步、削峰。但"第一次把消息真正发出去"的门槛依旧不小:

  • 需要装 Erlang?
  • 管理界面怎么开?
  • 消息会不会一发就丢?

这篇文章带你 10 分钟跑通第一个可生产的 RabbitMQ 示例,代码不足 80 行,却覆盖持久化 + 手动 ACK + 连接断线重试等生产级要素,复制即可运行。


1. 一键启动 RabbitMQ

不想装 Erlang?Docker 一把梭:

bash 复制代码
docker run -d --hostname rabbit \
  --name rabbit \
  -p 5672:5672 \
  -p 15672:15672 \
  rabbitmq:3.12-management

浏览器打开 http://localhost:15672

账号/密码:guest / guest

能看到队列、消息速率、节点内存,调试神器 get✔


2. Python 依赖仅一个包

bash 复制代码
pip install pika==1.3.2

3. 队列与消息:先声明,再使用

RabbitMQ 的哲学:队列只创建一次,谁先到谁声明

示例里把 durable=True 打开,即使 MQ 重启,队列元数据也不会丢。


4. 生产者代码(producer.py

python 复制代码
import pika, sys

QUEUE = 'demo_queue'

def main():
    conn = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
    ch = conn.channel()
    ch.queue_declare(queue=QUEUE, durable=True)          # 持久化队列

    for i in range(10):
        body = f'hello {i}'
        ch.basic_publish(exchange='',
                         routing_key=QUEUE,
                         body=body,
                         properties=pika.BasicProperties(delivery_mode=2))  # 持久化消息
        print(f' [x] Sent "{body}"')
    conn.close()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        sys.exit()

运行结果:

csharp 复制代码
 [x] Sent "hello 0"
 [x] Sent "hello 1"
 ...
 [x] Sent "hello 9"

5. 消费者代码(consumer.py

python 复制代码
import pika, time, sys

QUEUE = 'demo_queue'

def callback(ch, method, properties, body):
    print(f' [x] Received {body.decode()}')
    time.sleep(1)                               # 模拟耗时
    print(' [x] Done')
    ch.basic_ack(delivery_tag=method.delivery_tag)  # 手动 ack

def main():
    conn = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
    ch = conn.channel()
    ch.queue_declare(queue=QUEUE, durable=True)
    ch.basic_qos(prefetch_count=1)              # 公平分发
    ch.basic_consume(queue=QUEUE, on_message_callback=callback)
    print(' [*] Waiting for messages. To exit press CTRL+C')
    ch.start_consuming()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        sys.exit()

运行后,每秒处理 1 条消息,10 秒完成全部任务;

RabbitMQ UI 中 Messages 从 10 → 0,没有一条积压。


6. 小结:我们到底做了什么?

关键点 命令/参数 作用
队列持久化 queue_declare(durable=True) MQ 重启队列不丢
消息持久化 delivery_mode=2 服务器掉电消息不丢
手动 ACK basic_ack 消费者崩溃时消息可重新投递
公平分发 basic_qos(prefetch_count=1) 慢消费者不会被压垮

把这 4 项配置搬到生产环境,你就已经战胜了 80% 的"消息丢失"事故。


7. 下一步可以玩什么?

  1. demo_queue 换成 topic 模式,实现日志级别路由;
  2. RPC 模式做同步调用,假装自己是一个微服务网关;
  3. 开镜像队列 + 集群,Kill 掉任一节点,消息依旧在线;
  4. 给消费端加 retry + dead-letter-exchange,自动重试 3 次后进入死信队列,人工处理。

8. 一句鸡汤

消息队列的难点从来不在于"发消息",而在于"失败时消息还在"。

先让今天的 10 条消息不丢,再去考虑百万 QPS 的宏伟蓝图------脚下已出发,远方不远。

完整源码已上传 GitHub:
github.com/yourname/ra...

欢迎 Star & PR,祝大家排队愉快!

相关推荐
ldj202034 分钟前
从 API 调用到事件驱动:用 RabbitMQ /RocketMQ重构微服务通信架构
架构·rabbitmq
喝汽水的猫^3 小时前
Spring Boot + RabbitMQ 实战:消息可靠投递+防重复消费(可直接落地)
spring boot·rabbitmq·java-rabbitmq
8Qi81 天前
RabbitMQ高级篇:消息可靠性、幂等性与延迟消息
java·分布式·微服务·中间件·rabbitmq·springcloud
REDcker1 天前
RabbitMQ系列03 - AMQP分层与协议流转
分布式·rabbitmq
Albert Edison1 天前
【RabbitMQ】工作队列模式(使用案例)
分布式·rabbitmq·ruby
MoFe11 天前
【Rabbitmq】windows环境下搭建与使用
分布式·rabbitmq
REDcker1 天前
RabbitMQ系列04 - 流控与信用机制
分布式·rabbitmq
色空大师2 天前
【微服务项目-短信平台】
java·redis·微服务·rabbitmq·springcloud·短信
win x2 天前
RabbitMQ 七种工作模式
分布式·rabbitmq
REDcker2 天前
RabbitMQ系列01 - 消息中间件与 MQ:在分布式系统里解决什么问题
分布式·rabbitmq