最佳实践与 FAQ
完整使用流程
前置条件
- MBS 服务已部署并正常运行
- 管理员已在 MBS 管理后台创建了 Broker 和 Queue
- 已获取 API Token(具有目标 Queue 的相应权限)
- Callback URL 对应的主机名/IP 已加入白名单
第一步:创建 MBS Connector 实例
- 在 Connector 类型的 PBC 中新建 Connector
- 选择 ConnectorType 为 MBS
- 填写 Base URL(MBS 服务地址)和 Token(API 认证令牌)
- 保存
第二步:在 Flow 中推送消息
在 Flow 设计器中添加 Action 节点:
- 选择 MBS Enqueue (消息推送) Action
- 关联已创建的 MBS Connector 实例
- 填写 Broker Name、Queue Name、Message Body
- 获取返回的
messageId(可选,用于追踪)
第三步:注册消息订阅
在 Flow 中(或系统初始化时)调用:
- 选择 MBS Subscribe (消息订阅) Action
- 填写 Broker Name、Queue Name、Subscriber ID、Callback URL
- 按需配置 ACK Timeout 和 Retry
第四步:消费消息并 ACK
消费者服务收到推送后:
- 从请求头提取
X-Message-Id - 处理业务逻辑
- 通过 MBS ACK (消息确认) Action 确认消费
最佳实践
1. 消费者回调响应(最重要)
确保 Webhook 端点返回 {"consumer": "xxx"} 格式的 JSON 响应。 这是 MBS 判定推送成功的必要条件。
推荐的消费者回调流程:
收到推送 → 处理消息 → 调用 ACK 接口 → 返回 {"consumer": "xxx"}
如果返回纯文本(如 OK)、空响应、或不含 consumer 字段的 JSON,MBS 会判定推送失败并递增连续失败计数。
2. 消息幂等性(重要)
由于 MBS 使用 "at-least-once" 投递语义,同一消息可能被推送多次。消费者必须保证消息处理的幂等性。
推荐做法:
- 使用
X-Message-Id做去重判断(在数据库或 Redis 中记录已处理的 messageId) - 业务逻辑设计为可重入(同一消息处理多次,最终结果一致)
- 使用数据库唯一约束防止重复写入
示例去重逻辑:
app.post('/webhook', async (req, res) => {
const messageId = req.headers['x-message-id'];
// 检查是否已处理过
if (await isMessageProcessed(messageId)) {
res.status(200).send('Already processed');
return;
}
// 处理业务
await processMessage(req.body);
// 标记为已处理
await markMessageProcessed(messageId);
// 返回 200
res.status(200).send('OK');
});
2. ACK 超时设置
| 原则 | 说明 |
|---|---|
| 超时 > 最大处理耗时 | 避免业务还在处理中就被判定为超时 |
| 超时 = 平均耗时 x 3~5 | 留出网络抖动和偶发慢请求的余量 |
| 不确定时设大值 | 设 120 秒比设 5 秒风险小 |
3. broker_name 一致性
ACK 请求中的 brokerName 路径参数必须与创建订阅时使用的 Broker 名称完全一致(区分大小写)。如果不匹配:
- ACK 返回 404
- 消息超时后被重新投递
- 最终触发连续失败退订
4. ACK 超时设置
- 快速响应 - Webhook 端点应在 5 秒内返回 HTTP 200
- 异步处理 - 如业务逻辑耗时较长,先返回 200(表示收到),异步处理后再 ACK
- 非 2xx = 失败 - 返回非 2xx 状态码会被 MBS 视为投递失败,触发重试
推荐模式:
收到推送 → 立即返回 200 → 异步处理业务 → 处理完成调用 ACK
4. Token 最小权限原则
- 每个业务服务使用独立的 Token
- 按实际需要分配最小权限:
- 只需发消息的服务:仅 write 权限
- 只需消费消息的服务:仅 read 权限
- 定期轮换 Token
5. Subscriber ID 命名规范
| 格式 | 示例 | 适用场景 |
|---|---|---|
{服务名}-{实例号} | order-service-01 | 多实例部署的服务 |
{服务名}-{环境} | order-service-prod | 单实例服务 |
{服务名}-{Pod名} | order-service-pod-abc123 | K8s 环境 |
6. Callback URL 设计
推荐使用占位符实现路由分发:
http://gateway:8080/mbs-webhook/{BROKER_NAME}/{QUEUE_NAME}
这样一个消费者服务可以同时订阅多个 Queue,通过 URL 路径区分消息来源,在内部路由到不同的 Handler。
7. 错误处理
生产者端(Enqueue 失败):
- 记录失败日志,包含消息内容和错误信息
- 根据业务需求决定是否重试
- 重试时注意幂等性(避免重复发送造成重复消费)
消费者端(处理失败):
- 不要 ACK,让 MBS 在超时后自动重新投递
- 如果是明确不可恢复的错误(如消息格式错误),仍然 ACK 并记录到死信日志
- 避免让错误消息一直重试导致后续消息堆积
MBS 管理后台
访问地址
http://mbs-host:8080/mbs/ui/
登录
使用管理员密码登录(默认 admin,可通过 MBS_ADMIN_PASSWORD 环境变量修改)。
管理功能
| 功能 | 说明 |
|---|---|
| Broker 管理 | 查看/新建/编辑 Broker,监控连接状态 |
| Queue 管理 | 查看/新建 Queue,查看队列的订阅者列表 |
| Token 管理 | 创建/编辑/删除 Token,配置权限 |
| 白名单配置 | 管理 Callback URL 白名单 |
| 健康状态 | 查看各 Broker 后端的连接健康状况 |
API 错误码参考
| 错误码 | HTTP 状态码 | 说明 | 解决方案 |
|---|---|---|---|
AUTHENTICATION_ERROR | 401 | Token 缺失或无效 | 检查 Connector 中配置的 Token |
AUTHORIZATION_ERROR | 403 | 无对应权限 | 联系管理员为 Token 添加权限 |
INSTANCE_NOT_FOUND | 404 | Broker 不存在 | 确认名称拼写,或联系管理员创建 |
MESSAGE_NOT_FOUND | 404 | 消息不存在或已确认 | 消息可能已被 ACK 或已超时清理 |
INSTANCE_UNAVAILABLE | 503 | Broker 连接不可用 | 联系管理员检查 Broker 后端状态 |
INVALID_REQUEST | 400 | 请求格式错误 | 检查参数是否完整、格式是否正确 |
PAYLOAD_TOO_LARGE | 413 | 消息体超过大小限制 | 缩小消息体,或联系管理员调整限制 |
常见问题
Q: Enqueue 返回 401 错误?
A: Token 无效或已过期。解决方案:
- 在 MBS 管理后台确认 Token 是否存在且有效
- 重新获取 Token 并更新 Connector 配置
Q: Enqueue 返回 403 错误?
A: Token 没有对应 Queue 的 write 权限。解决方案:
- 在 MBS 管理后台编辑 Token 的权限配置
- 为目标
{brokerName}/{queueName}添加 write 权限
Q: Subscribe 报白名单校验失败?
A: Callback URL 的主机名/IP 不在白名单中。解决方案:
- 联系管理员在 MBS 管理后台添加白名单条目
- 确认主机名格式正确(不带协议、端口、路径)
Q: 消息推送后消费者没有收到?
排查步骤:
- 确认消费者服务正常运行且 Callback URL 可达
- 确认 Callback URL 对应的端口已开放
- 检查 MBS 管理后台中该订阅是否仍然有效(是否因连续失败被自动退订)
- 检查消费者服务日志是否有异常
Q: 同一条消息被重复推送?
A: ACK 未在超时时间内完成。解决方案:
- 增大 Subscribe 中的
messageAckTimeout值 - 优化消费者处理速度
- 改为异步处理模式(先返回 200,再异步 ACK)
- 确保消费者逻辑具有幂等性
Q: 如何查看消息是否推送成功?
A: 通过 MBS 管理后台查看:
- 进入目标 Queue 的详情页
- 查看订阅者列表中的投递状态和最近活动时间
- 如果有投递失败,会显示失败次数和最近失败原因
Q: 订阅被自动退订了怎么办?
A: 当连续推送失败达到 retry 次数后,订阅会被自动移除。解决方案:
- 检查并修复消费者服务的问题
- 重新调用 Subscribe Action 创建订阅
- 考虑增大
retry值(但不建议设为 0)
Q: 如何在 Flow 中同时发送消息和等待 ACK?
A: 推荐分离生产者和消费者的逻辑:
- 生产者 Flow - 只负责调用 Enqueue 推送消息
- 消费者服务 - 独立的 Webhook 端点,收到消息后处理并 ACK
- 两者通过 MBS 解耦,无需在同一个 Flow 中等待
Q: 支持哪些消息格式?
A: MBS 对消息格式不做限制。消息体以二进制方式存储和投递,支持:
- JSON
- XML
- 纯文本
- 二进制数据
- 任意自定义格式
消费者需要自行按约定格式解析消息内容。
Q: 如何选择 FANOUT 还是 QUEUE 投递模式?
A:
- FANOUT(广播):所有订阅者都需要收到每条消息(事件通知、数据同步)
- QUEUE(轮播):每条消息只需要一个消费者处理(任务分发、负载均衡)
FANOUT 模式下每个订阅者独立投递、独立 ACK,某个订阅者失败不影响其他订阅者。
Q: CETA 流程接收 MBS 推送后,连续失败计数一直为 1?
A: 两个最常见的原因:
- 回调流程未设置
inMemory: true- 非内存模式下流程触发后立即返回,响应中不包含consumer字段。解决:将 TRIGGER 节点的inMemory设为true。 - 流程中未设置
consumer输出值 - 即使是内存执行,没有通过"设置流程输出值"节点设置consumer字段也不行。解决:添加输出值节点。
详见 Flow 集成指南。
Q: MBS 的健康检查接口是什么?
A:
- 存活探针:
GET /health- 返回 200 表示进程存活 - 就绪探针:
GET /readiness- 返回 200 表示数据库和 Broker 连接正常
这两个端点无需认证。