RocketMQ之消息机制篇

359 阅读5分钟

rocketMQ实现消息步骤

  1. 发送消息:消息生产者发送消息到RocketMQ的Broker服务器。
  2. 存储消息:Broker接收到消息后,先将消息存储在CommitLog中,然后返回确认信息给生产者。
  3. 发送确认信息:一旦消息被存储,Broker会发送一个确认信息给生产者。如果生产者接收到确认信息,那么表示消息已经成功存储在Broker;否则,生产者可以选择重新发送消息。
  4. 消费消息:当消费者从Broker拉取消息时,Broker会将消息标记为已消费。
  5. 返回确认信息:消费者处理完消息后,需要向Broker发送确认信息,表示消息已处理。如果Broker接收到确认信息,那么将该消息标记为已确认。
  6. Broker在接收到消费者的确认信息后,将会把这个确认信息记录在Consumer Offset中,如果没有接收到该确认信息,Broker会认为该消息还未被消费。

通过以上步骤,RocketMQ实现了消息的产生、存储、消费以及确认的完整过程。

图片

RocketMQ实现消息确认机制

RocketMQ实现消息确认机制的主要方式有以下三种:

1、单向通信:发送方向接收方发送消息后,只管发送不管接收,也就是发送方没有从接收方得到确认。这是最低的QoS(服务质量)等级。

   @Service
   public class ProducerService {   
    @Autowired    
    private RocketMQTemplate rocketMQTemplate;
      public void sendOneway(String topic, String message) {  
      
             rocketMQTemplate.sendOneWay(topic,MessageBuilder.withPayload(message).build());    
             }
             }

2、同步发送:发送方向接收方发送消息后,会等待接收方的确认消息。如果接收方在规定时间内发送确认信息,那么消息发送成功,否则消息发送失败。这是中等的QoS等级。

这种方式可以用于对消息丢失有严格要求的场景。

public SendResult syncSend(String topic, String message) {       
        return rocketMQTemplate.syncSend(topic, MessageBuilder.withPayload(message).build());
}

3、异步发送:发送方向接收方发送消息后,不会立刻等待接收方的确认消息,而是通过回调的方式在接收方发送确认信息后接收确认。这是最高的QoS等级。

        这种方式既可以确保消息的成功率,又可以提高消息发送的效率。

 rocketMQTemplate.asyncSend(topic, MessageBuilder.withPayload(message).build(), new SendCallback() {     
     @Override            
     public void onSuccess(SendResult sendResult) {                // 消息发送成功的回调          
       }
     @Override            
     public void onException(Throwable throwable) {                // 消息发送失败的回调            }        
     });

图片

如何实现消息的幂等性?

        RocketMQ主要通过以下方式来实现消息的幂等性:

  1. Message ID:RocketMQ生成消息时会为每条消息生成一个唯一的ID,这个ID在整个消息系统中是唯一的。如果生产者因为某些原因重复发送了消息,Broker可以通过比对Message ID来识别和排除重复的消息。
  2. Consumer Offset:RocketMQ的消费者在消费消息后,会将已消费的消息的位置(Offset)保存起来,这样如果消费者重启或者因为其他原因需要重新消费消息时,可以根据这个Offset来消费没有消费过的消息,避免了重复消费。
  3. 重试队列:RocketMQ中如果消费失败,消息将被放到重试队列,只有在多次重试仍旧失败后才会被放到死信队列,从而避免了消息的丢失。

通过组合使用以上策略,RocketMQ可以在一定程度上保证消息处理的幂等性,避免了重复消费和丢失消息的问题。

这些方法不仅限于RocketMQ,对于大多数的消息系统比如Kafka,RabbitMQ等,实现消息幂等性的方法都大同小异。

如何实现可靠性?

  1. 分布式系统:RocketMQ采用分布式系统,它可以创建多个Topic和多个Broker,负载均衡分配和管理消息。
  2. 同步刷盘和异步刷盘:为了保证Broker在收到生产者的消息之后,即时宕机也不会丢失消息,需要及时将消息持久化到磁盘。这就有了两种策略:一种是同步刷盘,也就是每收到一条消息就同步到磁盘,可以保证消息绝对不丢失,但是性能会比较低;一种是异步刷盘,也就是累积一定量的消息或者一定时间后,再批量刷入磁盘,性能可以得到极大提升,但在宕机时可能会丢失一部分消息。RocketMQ会根据需要选择不同的策略。
  3. 消息重试:RocketMQ中的消费者有重试机制,如果消费失败,会尝试重新消费。
  4. 消息持久化:RocketMQ将所有消息都保存在磁盘中,即使在内存数据丢失或服务器宕机的情况下,也可以从磁盘中找回数据。
  5. 顺序消息:RocketMQ支持顺序消息,可以保证消息的顺序性,保证在高并发情况下,消息的消费顺序与发送顺序一致。
  6. 集群同步:如果启用了RocketMQ的主从同步特性,一条消息在主节点写入成功后,会等待从节点写入成功才会向生产者返回成功。这种机制可以进一步保证消息不丢失,但是会稍微降低性能。

欢迎关注我的公众号:程序员技术成长之路