RocketMQ总结与补充

1. 消息队列优缺点

优点:
1. 异步
2. 解耦
3. 削峰
缺点:
1. 系统可用性越低:外部依赖越多,依赖越多,出问题风险越大
2. 系统复杂性挺高:需要考虑多种场景,比如消息重复消费,消息丢失
3. 需要更多的机器的人力:消息队列一般集群部署,而且需要运维和监控,例如topic申请等

2. 消息队列怎么避免重复消费

任何一个消息队列无法保证消息不重复消费,RocketMQ也一样不保证消息不重复,如果你的业务需要保证严格的不重复消息,需要你在业务端去重。

接口幂等性保证,消费端处理业务消息要保持幂等性

Redis:

  • 使用setNX(),做消息id去重,java版本目前不支持设置过期时间,如果再用expire则不是原子操作,可以用下面方式实现分布式锁
# 加锁
String result = redisUtil.setLock(lock_key, value, "NX", "PX", 8000);

# 解锁
 String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
 # 成功返回1 失败返回0
 Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(value));

  • 使用Incr
    使用Incr原子操作:key自增,返回值大于0则说明消费过
    上述两个方式都可以,但是不能用于分布式锁,考虑原子问题,但是排重可以不考虑原子问题,数据量多需要设置过期时间

3. RocketMQ如何保证消息的可靠性传输

  • producer端

    1. 不采用oneway发送,使用同步或者异步方式发送,做好重试,但是重试的Messae key必须唯一
    2. 投递的日志需要保存,关键字段,投递时间,投递状态、重试次数、请求体、响应体
  • broker端

    1. 双主双从架构,NameServer需要多节点
    2. 同步双写、异步刷盘(同步刷盘则可靠性更高,但是性能差点,根据业务选择)
  • consumer端

    1. 消息消费务必保留日志,即消息的元数据和消息体
    2. 消费端务必做好幂等性处理
  • 投递到broker端后

    1. 机器断点重启:异步刷盘,消息丢失;同步刷盘消息不丢失
    2. 硬件故障:可能存在丢失,看队列架构

4. 消息发生大量堆积应该怎么处理

线上故障了,怎么处理

  • 消息堆积了10小时,有几千万条消息待处理,现在怎么办?
  • 修复consumer,然后慢慢消费?也需要几小时才可以消费完成,新的消息怎么办?

正确的姿势:

  • 临时topic队列扩容,并提高消费者能力,但是如果增加Consumer数量,但是堆积的topic里面的message queue数量固定,过多的consumer不能分配到messae queue
  • 编写临时处理分发程序,从旧topic快速读取到新topic中,新topic的queue数量扩容多倍,然后再启动更多consumer进行在临时新的topic里消费

5. RocketMQ高性能的原因分析

  • MQ架构配置

    1. 顺序写,随机读,零拷贝
    2. 同步刷盘SYNC_FLUSH和异步刷盘ASYNC_FLUSH, 通过flushDiskType配置
    3. 同步复制和异步复制,通过brokerRole配置,ASYNC_MASTER,SYNC_MASTER,SLAVE
    4. 推荐同步复制(双写),异步刷盘
  • 发送端高可用
    双主双从架构:创建Topic对应的时候,MessageQueue创建在多个Broker组上即相同的Broker名称,不同的brokerid;当一个Master不可用时,组内其他的Master仍然可用。但是机器资源不足的时候,需要手工把slave转成master,目前不支持自动转换,可用shell处理

  • 消费高可用

    1. 主从架构:Broker角色,Master提供读写,Slave只支持读
    2. Consumer不用配置,当Master不可用或者繁忙的时候,Consumer会自动切换到Slave节点进行能读取
  • 提高消息的消费能力

    • 并行消费
      1. 增加多个节点
      2. 增加单个Consumer的并行度,修改consumerThreadMin和consumerThreadMax
      3. 批量消费,设置Consumer的consumerMessageBatchMaxSize,默认是1,如果为N,则消息多的时候,每次收到的消息为N条
    • 择Linux Ext4文件系统,Ext4文件系统删除1G大小的文件通常耗时小于50ms,而Ext3文件系统耗时需要1s,删除文件时磁盘IO压力极大,会导致IO操作超时

6. 消息队列常见面试题总结

  • 为什么使用消息队列
  • 消息队列技术选择
  • 如果保证消息队列高可用
  • 如何保证消息传输的可靠性
  • 如何保证消息的不重复消费
  • 如何保证消息的顺序消费
  • 消息堆积怎么处理
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页