RocketMQ 最佳实践及基本规范(二)

457 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情

最佳实践

  1. 建议部署多master,多slave实现高可用,消灭单点。

  2. 强制增加消息监控(可以初步实现为企业微信群通知)

  3. 业务繁忙场景,建议producer和consumer分开实现为可单独部署的应用中。这样可以单独横向扩展。

  4. Topic 由于不同的项目应用可能会使用同一个 rocketmq 服务器,所以在项目应用中要保持topic的唯一性,
    一般的做法是在 topic 的命名中加入项目的名称及环境的标识,例如 yl-south-courese
    一个group 必须只能对应一个 topic,命名时 并加上topic的标识。
    topic的命名规范: 团队-项目-业务
    Group 的命名: <topic的name>-自定义

  5. Key 每个消息在业务层面的唯一标识码,要设置到 keys 字段,方便将来定位消息丢失问题。服务器会为每个消息创建索引(哈希索引),
    应用可以通过 topic,key来查询这条消息内容,以及消息被谁消费。由于是哈希索引,请务必保证key 尽可能唯一(可以用 uuid),这样可以避免潜在的哈希冲突。

    String orderId= "20034568923546";  //订单Id
    message.setKeys(orderId);
    
  6. 日志
    消息发送成功或者失败,要打印消息日志,务必要打印 send result 和key 字段。
    如果消息用的多,日志记得要单独设置一个文件,否则查找的时候会很费力。

  7. 发送

    send消息方法,只要不抛异常,就代表发送成功。但是发送成功会有多个状态,在sendResult里定义(这个 sendResult 要打记录下来,打印到日志或者数据库)。

    • SEND_OK:消息发送成功
    • FLUSH_DISK_TIMEOUT:消息发送成功,但是服务器刷盘超时,消息已经进入服务器队列,只有此时服务器宕机,消息才会丢失
    • FLUSH_SLAVE_TIMEOUT:消息发送成功,但是服务器同步到Slave时超时,消息已经进入服务器队列,只有此时服务器宕机,消息才会丢失
    • SLAVE_NOT_AVAILABLE:消息发送成功,但是此时slave不可用,消息已经进入服务器队列,只有此时服务器宕机,消息才会丢失

    如果对消息的发送性能要示比较高,可以采用异步发送的模式发送数据。

    如果对同一个业务,会有多个消费者实例(负载),要把这几个实例放入同一个group中,避免重复消费。

    对于发送失败的消息,可以将消息存储到DB中,后台定时重试,并设置重试的次数。

  8. 消费

    • 幂等 RocketMQ使用的消息原语是At Least Once,所以consumer可能多次收到同一个消息,此时务必做好幂等。
    • 日志 消费时记录日志,以便后续定位问题。
    • 批量消费 尽量使用批量方式消费方式,可以很大程度上提高消费吞吐量。
    • 在一个应用中,消费者的实例要控制,并限制消费线程池的数量。
    • 对于同一个 topic 、tag的消息,不同的 group的消费都都会消费一次。
  9. Rocketmq console
    使用 Rocketmq console 可以在开发过程中对 Rocketmq的topic 、message等信息进行监控,方便开发。