跳到主要内容
版本:1.0.0(开发版)

发送并消费第一批消息

本教程将本地 Rust 服务与一组配套的生产者/LitePull 应用连接起来。你将创建主题和消费者组,发送五条消息,处理消息并提交组的偏移量。所有命令均在仓库根目录执行。

发送前的准备​

NameServer 与 Broker 必须已使用教程配置启动。按照本地搭建说明,通过 cluster clusterList 确认 DocsCluster 和 docs-broker。先构建示例,再启动只有一分钟等待窗口的消费者:

cargo build --manifest-path rocketmq-website/examples/first-message/Cargo.toml
配置项值
NameServer127.0.0.1:9876
主题DocsFirstMessage
消费者组docs_first_message_consumer
生产者组docs_first_message_producer
读写队列教程 Broker 上各四个
订阅主题中的全部消息

可执行程序在完整源码中使用这些常量。两条运行命令使用同一份源码和同一主题。rocketmq-example 中的独立演示则使用不同的内置主题。

1. 创建主题和消费者组​

运行管理命令前,在当前终端中设置 NameServer。PowerShell:

$env:NAMESRV_ADDR = "127.0.0.1:9876"

Unix shell:

export NAMESRV_ADDR=127.0.0.1:9876

当前 clusterList 和 updateSubGroup 子命令使用环境变量,不接受 -n。下面的主题和进度查询命令各自支持 -n,它不是 CLI 全局参数。

以下两条命令会修改集群元数据,请仅对专用本地集群执行:

cargo run -p rocketmq-admin-cli -- topic updateTopic -t DocsFirstMessage -c DocsCluster -r 4 -w 4 -n 127.0.0.1:9876
cargo run -p rocketmq-admin-cli -- consumer updateSubGroup -g docs_first_message_consumer -c DocsCluster

updateTopic 创建或更新主题配置,updateSubGroup 创建或更新消费者组配置。不要复用现有应用的资源名:重复执行 update 是配置操作,不只是查询。

使用以下只读命令检查路由:

cargo run -p rocketmq-admin-cli -- topic topicRoute -t DocsFirstMessage -n 127.0.0.1:9876

路由应包含 docs-broker,公布 127.0.0.1:10911,并具有可读、可写队列。如果未立即返回路由,等待 Broker 路由注册传播后再次查询。返回的地址不可达时,即使 NameServer 可达,也仍然属于 Broker 地址公布问题。

2. 启动消费者​

保持两个服务运行,打开第三个终端:

cargo run --manifest-path rocketmq-website/examples/first-message/Cargo.toml -- consume

等待出现 CONSUMER_STARTED。应用先订阅,再启动,使用一秒轮询超时,最多等待 60 秒以接收至少五条消息。没有可消费数据时,轮询返回空批次属于正常情况。

对于没有已存储进度的新组,ConsumeFromFirstOffset 允许读取已有数据。对于已有组,已存储偏移量优先;该设置不会强制重放历史消息。

3. 从另一个终端发送​

在消费者的 60 秒窗口内执行:

cargo run --manifest-path rocketmq-website/examples/first-message/Cargo.toml -- produce

生产者发送五条小消息,每次调用超时为三秒,输出 SEND 0 到 SEND 4、返回状态、消息 ID 和队列偏移量。缺少结果或非 SendOk 状态均按错误处理。发生错误时,命令在清理资源后结束。

消费者输出 RECEIVED id=... 和 OFFSET_COMMIT_REQUESTED received=...。消息 ID、批次划分和接收顺序可能不同。如果主题仍有旧消息,计数可能超过五。处理非空批次后,应用提交进度,并在总数达到至少五条时退出。

这些输出展示教程中的应用链路,不能证明全局有序、业务精确一次执行、复制或崩溃持久性。示例输出消息 ID 和计数,不记录消息体。

4. 理解运行结果​

生产者返回值反映发送,消费者输出反映应用处理,commit_all 反映消费者组的消费进度。它们不会自动与外部数据库组成一个事务。 当前 LitePull 的 commit_all 更新客户端偏移量存储状态,与持久化分离,并可能在内部记录队列级错误。因此,OFFSET_COMMIT_REQUESTED 表示调用返回,不代表持久的 Broker 确认。详见提交语义。

示例将打印每个 ID 视为处理完成,然后提交。用于实际应用时,应先完成业务处理,再提交进度。如果一批消息只成功处理一部分,不要直接提交整个批次;需要明确重试、幂等,以及可以安全推进的连续消费进度。

应用持有一个 RuntimeOwner,在其下创建 Arc<ClientRuntime>,并传入客户端 facade 的 builder。返回前依次关闭生产者/消费者、共享客户端运行时、运行时所有者和遥测。改造示例时应保留该生命周期。

重复运行与诊断​

再次运行时,先启动消费者,再发送五条新消息。复用同一消费者组通常会从已提交进度继续。如果存在旧的未消费数据,消费者可能在新生产者启动前就完成接收;本演示没有通过唯一运行 ID 关联消息。

消费者超时时,按照首次诊断检查返回的 Broker 地址、主题和组是否一致、队列分配以及已存储进度。不要首先删除存储或重置偏移量。

扩展示例前,阅读生产者概览、LitePull 消费和投递与重试。