AMQP/JMS 风格的消息代理

将单个消息分配给消费者,消费者在成功处理后确认每条消息。消息被确认后从代理中删除。 适合作为一种异步 RPC。

  • RabbitMQ
  • ActiveMQ
  • HornetQ
  • Qpid
  • TIBCO Enterprise MEssage Service
  • IBM MQ
  • Azure Service Bus
  • Google Cloud Pub/Sub

多个消费者

负载均衡式

每一条消息都只被传递给其中一个消费者。

扇出式

每条消息都被传递给所有消费者。

确认和重新传递

为了确保消息不会丢失,消息代理使用确认:客户端必须在处理完消息后显式的告诉代理,以便代理可以将其从队列中移除。

如果客户端的连接关闭或超时,而代理没有收到确认,则认为消息未处理,因此它将消息重新传递给另一个消费者。

消息顺序性

即使消息代理试图保留消息顺序(标准要求),负载均衡与重新传递的组合也不可避免地导致消息被重新排序。

基于日志的消息代理

  • 代理将分区中的所有消息分配给相同的消费者节点,并始终以相同的顺序发送消息。
  • 通过分区机制来实现并行(写在多个磁盘上突破磁盘带宽),消费者通过检查他们处理的最后一条消息的偏移量来跟踪进度。
  • 代理将消息保存在磁盘上,因此如果有必要,可以回退并重新读取旧消息。

代表性的有:

基于日志的消息存储

参照 LSM-Tree 和 B-tree 的 WAL,可以使用相同的结构来实现消息代理: 生产者通过将消息追加到日志的末尾来发送消息,消费者通过依次读取日志来接收消息。 如果消费者读到日志的末尾,它就开始等待新消息被追加的通知。

通过对日志进行分区突破单个磁盘所能体能的带宽吞吐上线。

代理为每个消息分区分配了一个单调递增的序列号或偏移量,保证了分区内的消息完全有序。

消费者偏移量:记录哪些消息已经被处理,减少 ACK 开销

磁盘空间:分段,定期删除

消费者跟不上生产者:增加 LAG 报警

重新处理消息:重置偏移量