[python]操作rocketmq(实战)

262 阅读3分钟

以下是针对 Python 开发者操作 RocketMQ 的完整指南,从环境搭建到生产消费代码实现,结合最佳实践和常见问题解决方案整理而成:


一、环境搭建与配置

1. 本地 RocketMQ 服务搭建(开发测试用)

  • 安装依赖
    • Java 8+(RocketMQ 依赖)
    • 下载 RocketMQ 二进制包:
      wget https://downloads.apache.org/rocketmq/5.0.0/rocketmq-all-5.0.0-bin-release.zip
      unzip rocketmq-all-5.0.0-bin-release.zip
      cd rocketmq-5.0.0
      
  • 启动服务
    # 启动 NameServer
    nohup sh bin/mqnamesrv &
    
    # 修改 Broker 配置(conf/broker.conf)
    brokerIP1 = 你的本地IP(如 192.168.1.10)  # 避免用 127.0.0.1
    
    # 启动 Broker
    nohup sh bin/mqbroker -n localhost:9876 -c conf/broker.conf &
    
  • 验证服务
    # 创建测试 Topic
    sh bin/mqadmin updatetopic -n localhost:9876 -t TestTopic -c DefaultCluster
    

2. Python 环境配置

  • 安装依赖
    # 安装 C++ 依赖库(Mac M1 需 Rosetta 转译)
    wget https://github.com/apache/rocketmq-client-cpp/releases/download/2.0.0/rocketmq-client-cpp-2.0.0-bin-release.darwin.tar.gz
    tar -xzf rocketmq-client-cpp-2.0.0-bin-release.darwin.tar.gz
    sudo cp rocketmq-client-cpp/lib/librocketmq.dylib /usr/local/lib/
    
    # 安装 Python SDK
    pip install rocketmq-client-python
    
  • 解决 M1 芯片兼容问题
    # 创建 x86 虚拟环境
    CONDA_SUBDIR=osx-64 conda create -n rocketmq-x86 python=3.10
    conda activate rocketmq-x86
    

二、生产者与消费者基础代码

1. 生产者示例(同步发送)

from rocketmq.client import Producer, Message
import json

producer = Producer('PID-demo')  # Producer Group ID
producer.set_namesrv_addr('192.168.1.10:9876')  # NameServer 地址
producer.start()

msg = Message('TestTopic')
msg.set_keys('order-123')  # 消息唯一标识(可追踪)
msg.set_tags('Pay')        # 消息分类标签
msg.set_body(json.dumps({"user_id": 1001, "amount": 299.0}).encode())

try:
    ret = producer.send_sync(msg)
    print(f"消息发送成功: ID={ret.msg_id}, 状态={ret.status}")
except Exception as e:
    print(f"发送失败: {e}")

producer.shutdown()

2. 消费者示例(Push 模式)

from rocketmq.client import PushConsumer
import time

def callback(msg):
    print(f"收到消息: ID={msg.id}, Body={msg.body.decode()}, Tag={msg.get_tags()}")

consumer = PushConsumer('CID-demo')  # Consumer Group ID
consumer.set_namesrv_addr('192.168.1.10:9876')
consumer.subscribe('TestTopic', callback, '*')  # '*' 订阅所有 Tag
consumer.start()

print("消费者已启动...")
while True:
    time.sleep(3600)  # 保持进程运行

三、高级场景实现

1. 顺序消息处理

# 生产者(确保同一订单号的消息发到同一队列)
def queue_selector(mq_list, msg, arg):
    order_id = arg  # 如 arg="order-123"
    index = hash(order_id) % len(mq_list)
    return mq_list[index]

producer.send_sync(msg, queue_selector=queue_selector, arg="order-123")

# 消费者(需启用顺序模式)
consumer = PushConsumer('CID-order', orderly=True)  # 关键参数!

2. 异步发送(高性能场景)

def send_callback(ret):
    if ret.status == "SEND_OK":
        print(f"异步发送成功: {ret.msg_id}")
    else:
        print(f"异步发送失败")

producer.send_async(msg, send_callback)

3. 腾讯云 RocketMQ 适配

producer.set_namesrv_addr('公网接入点:9876')  # 控制台获取
producer.set_session_credentials('AK', 'SK', 'ALIYUN')  # 云平台认证

# 必须提前在控制台创建 Topic 和 Group,否则报错 No route info

四、常见问题解决

  1. OSError: incompatible architecture (have 'x86_64', need 'arm64')
    → 使用 Rosetta 转译或 x86 Conda 环境

  2. ProducerSendSyncFailed: No route info of this topic
    → 控制台确认 Topic 已创建且队列数 >0

  3. 消息堆积严重
    → 增加消费者实例数或调整 PullConsumer 批量拉取条数

  4. 顺序消息错乱
    → 检查生产者是否使用队列选择器,消费者是否设置 orderly=True


五、操作流程总结

graph TD
    A[环境准备] --> B[安装 Java 与 RocketMQ]
    A --> C[配置 Python SDK]
    B --> D[启动 NameServer 和 Broker]
    C --> E[编写生产者逻辑]
    C --> F[编写消费者逻辑]
    D --> G[创建 Topic/Group]
    E --> H[消息发送测试]
    F --> H
    H --> I[监控与问题排查]

提示:生产环境建议使用云服务(如腾讯云/TDMQ),避免自维护成本。重点注意:

  • M1 芯片需通过 CONDA_SUBDIR=osx-64 创建 x86 环境
  • 云平台必须预先创建 Topic 和 Group
  • 顺序消息需同时配置生产者队列选择与消费者 orderly=True

以上步骤覆盖了本地开发到云服务的全流程,示例代码可直接调试使用。遇到网络问题时可优先检查防火墙端口(9876/10911)。