消息队列中的几个基本概念

消息队列通常有生产者(Producer)、消费者(Consumer)和Broken三部分组成。其中生产者负责发送消息到Broken,Broken接收到消息后,投递给Consumer进行消费。

Consumer

consumer在消费消息时,通常有两种模式:推模式和拉模式。推模式指的是由Broken向Consumer推送消息,拉模式指的是由Consumer定时向Broken定时获取消息。在实际生产中,更多使用的是推这种模式。

Broken

Broken用来接收并存储消息,然后对消息进行投递。

消息队列特性

消息过滤

消息支持根据设置的属性进行过滤,这样可以有效减少Broken投递的消息数量和网络带宽。

事务消息

事务消息是类似XA的两阶段提交消息。实现原理如下:
1. ⽣产者先发送⼀条半事务消息到MQ
2. MQ收到消息后返回ack确认
3. ⽣产者开始执⾏本地事务
4. 如果事务执⾏成功发送commit到MQ,失败发送rollback
5. 如果MQ⻓时间未收到⽣产者的⼆次确认commit或者rollback,MQ对⽣产者发起消息回查
6. ⽣产者查询事务执⾏最终状态,如果本地事务执行成功,返回true,否则返回false;
7. 根据查询事务状态再次提交⼆次确认

image.png

消息可靠性

RocketMQ支持消息的高可靠,影响消息可靠性的几种情况:

  1. Broker非正常关闭
  2. Broker异常Crash
  3. OS Crash
  4. 机器掉电,但是能立即恢复供电情况
  5. 机器无法开机(可能是cpu、主板、内存等关键设备损坏)
  6. 磁盘设备损坏

1)、2)、3)、4)这4种属于硬件资源可立即恢复的情况,RocketMQ在这四种情况下能保证消息不丢,或者丢失少量数据(依赖刷盘方式是同步还是异步)。
5)、6)属于单点故障,且无法恢复,一旦发生,在此单点上的消息全部丢失。RocketMQ在这两种情况下,通过异步复制,可保证99%的消息不丢,但是仍然会有极少量的消息可能丢失。通过同步双写技术可以完全避免单点,同步双写势必会影响性能,适合对消息可靠性要求极高的场合。

一般情况下,考虑到性能,生产上会选择异步刷盘,主从异步复制的方式。如果出现消息没有投递,可以通过核对的方式发现并重新同步消息。

流量控制

消息实践

消息重复投递的问题

  • Broken无法保证消息不重复投递,需要由消费端做幂等处理;

RocketMQ为什么速度快

  • 顺序写入;
  • 异步刷盘;
  • Page Cache;

消息堆积的问题

如果是因为消息量级太大而导致Consumer处理消息处理不过来,可以考虑以下几个办法:

  • 订阅消息时,对消息进行过滤;
  • 系统扩容,通过增加机器的容量或者DB的容量,增加系统的吞吐量;
  • 通过多线程提升TPS;
  • 消息异步化处理;

如果是因为Consumer出现问题导致消息积压,可以有以下几种处理方式:

  • 消息异步化处理;
  • 暂时取消订阅关系,待问题修复后或者系统恢复正常后重新订阅。在这个过程中产生的脏数据,人工补齐;

https://github.com/apache/rocketmq/blob/master/docs/cn/concept.md