资料总结 资料总结
首页
go
java
云原生
  • mysql
  • redis
  • MongoDB
  • 设计模式详解
  • 数据结构与算法
  • 前端
  • 项目
  • 理论基础
  • 运营
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

linghui Wu

一只努力学飞的鱼
首页
go
java
云原生
  • mysql
  • redis
  • MongoDB
  • 设计模式详解
  • 数据结构与算法
  • 前端
  • 项目
  • 理论基础
  • 运营
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • java-se

  • jvm

  • mybatis

  • Netty

  • 爬虫 webmagic

  • spring

  • spring-cloud

  • 中间件

    • RabbitMQ

    • Kafka

    • RocketMQ

      • RocketMQ快速实战
      • 生产问题总结及性能优化
        • 生产者使用事务消息机制保证消息零丢失
        • RocketMQ配置同步刷盘+Dledger主从架构保证MQ自身不会丢消息
          • 同步刷盘
          • Dledger的文件同步
        • 消费者端不要使用异步消费机制
        • RocketMQ特有的问题,NameServer挂了如何保证消息不丢失?
        • 总结
          • 如何保证消息顺序
        • 局部有序
        • 全局有序
          • 快速处理积压消息
        • 确定有大量的消息积压?
        • 处理
          • MessageQueue > Consumer
          • MessageQueue < Consumer
          • 主从架构 切换成 Dledger高可用
          • 消息轨迹
        • 消息轨迹数据的关键属性
        • 消息轨迹配置
        • 数据存储
          • 系统级别的Topic
    • Zookeeper

    • ElasticStatic

  • flowable

  • idea工具

  • maven

  • ms

  • java部署

  • 原生安卓

  • java
  • 中间件
  • RocketMQ
wulinghui
2022-02-20
目录

生产问题总结及性能优化

# 如何保证消息不丢失

# 生产者使用事务消息机制保证消息零丢失

# RocketMQ配置同步刷盘+Dledger主从架构保证MQ自身不会丢消息

# 同步刷盘

# Dledger的文件同步

# 消费者端不要使用异步消费机制

# RocketMQ特有的问题,NameServer挂了如何保证消息不丢失?

当NameServer全部挂了后,生产者和消费者是立即就无法工作了的;只要有一个就没问题,能正常工作。

在这种情况下,RocketMQ相当于整个服务都不可用了,那他本身肯定无法给我们保证消息不丢失了。我们只能自己设计一个降级方案来处理这个问题了。

例如在订单系统中,如果多次尝试发送RocketMQ不成功,那就只能另外找给地方(Redis、文件或者内存等)把订单消息缓存下来,然后起一个线程定时的扫描这些失败的订单消息,尝试往RocketMQ发送。这样等RocketMQ的服务恢复过来后,就能第一时间把这些消息重新发送出去。

# 总结

这套方案带来的性能损失的代价可能远远大于部分消息丢失的代价

  • 生产者使用事务消息机制。
  • Broker配置同步刷盘+Dledger主从架构
  • 消费者不要使用异步消费。
  • 整个MQ挂了之后准备降级方案

# 如何保证消息顺序

# 局部有序

只保证一部分关键消息的消费顺序。

只需要将有序的一组消息都存入同一个MessageQueue里,这样MessageQueue的FIFO设计天生就可以保证这一组消息的有序。RocketMQ中,可以在发送者发送消息时指定一个MessageSelector对象,让这个对象来决定消息发入哪一个MessageQueue。这样就可以保证一组有序的消息能够发到同一个MessageQueue里。

# 全局有序

整个MQ系统的所有消息严格按照队列先入先出顺序进行消费。

Topic全局消息有序的方式,就是将Topic配置成只有一个MessageQueue队列(默认是4个)。这样天生就能保证消息全局有序了。

而这种方式对整个Topic的消息吞吐影响是非常大的,如果这样用,基本上就没有用MQ的必要了。

# 快速处理积压消息

# 确定有大量的消息积压?

  • 在Web控制台的主题页面,可以通过 Consumer管理 按钮实时看到消息的积压情况。
  • 也可以通过mqadmin指令在后台检查各个Topic的消息延迟情况。

# 处理

# MessageQueue > Consumer

如果Topic下的MessageQueue配置得是足够多的,那每个Consumer实际上会分配多个MessageQueue来进行消费。这个时候,就可以简单的通过增加Consumer的服务节点数量来加快消息的消费,等积压消息消费完了,再恢复成正常情况。最极限的情况是把Consumer的节点个数设置成跟MessageQueue的个数相同。但是如果此时再继续增加Consumer的服务节点就没有用了。

# MessageQueue < Consumer

如果Topic下的MessageQueue配置得不够多的话,那就不能用上面这种增加Consumer节点个数的方法了。这时怎么办呢? 这时如果要快速处理积压的消息,可以创建一个新的Topic,配置足够多的MessageQueue。然后把所有消费者节点的目标Topic转向新的Topic,并紧急上线一组新的消费者,只负责消费旧Topic中的消息,并转储到新的Topic中,这个速度是可以很快的。然后在新的Topic上,就可以通过增加消费者个数来提高消费速度了。之后再根据情况恢复成正常情况。

# 主从架构 切换成 Dledger高可用

在官网中,还分析了一个特殊的情况。就是如果RocketMQ原本是采用的普通方式搭建主从架构,而现在想要中途改为使用Dledger高可用集群,这时候如果不想历史消息丢失,就需要先将消息进行对齐,也就是要消费者把所有的消息都消费完,再来切换主从架构。因为Dledger集群会接管RocketMQ原有的CommitLog日志,所以切换主从架构时,如果有消息没有消费完,这些消息是存在旧的CommitLog中的,就无法再进行消费了。这个场景下也是需要尽快的处理掉积压的消息。

# 消息轨迹

# 消息轨迹数据的关键属性

Producer端 Consumer端 Broker端
生产实例信息 消费实例信息 消息的Topic
发送消息时间 投递时间,投递轮次 消息存储位置
消息是否发送成功 消息是否消费成功 消息的Key值
发送耗时 消费耗时 消息的Tag值

# 消息轨迹配置

打开消息轨迹功能,需要在broker.conf中打开一个关键配置:

traceTopicEnable=true // 默认是false关闭的

# 数据存储

  • 默认情况下,消息轨迹数据是存于一个系统级别的Topic ,RMQ_SYS_TRACE_TOPIC。
  • 这个Topic在Broker节点启动时,会自动创建出来。
  • 也支持客户端自定义轨迹数据存储的Topic。
  • 客户端的两个核心对象 DefaultMQProducer和DefaultMQPushConsumer,他们的构造函数中,都有两个可选的参数来打开消息轨迹存储
    • enableMsgTrace:是否打开消息轨迹。默认是false。
    • customizedTraceTopic:配置将消息轨迹数据存储到用户指定的Topic 。

# 系统级别的Topic

  • RMQ_SYS_TRACE_TOPIC 消息轨迹
  • RMQ_SYS_TRANS_HALF_TOPIC 事务消息HALF的TOPIC
  • SCHEDULE_TOPIC_XXX 延迟消息topic
编辑 (opens new window)
上次更新: 2023/01/24, 15:21:15
RocketMQ快速实战
Zookeeper快速使用

← RocketMQ快速实战 Zookeeper快速使用→

最近更新
01
架构升级踩坑之路
02-27
02
总结
02-27
03
语法学习
02-27
更多文章>
| Copyright © 2021-2025 Wu lingui |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式