如果发布者在收到确认之前终止,会发生什么情况?

我想确保某些类型的消息不会丢失,因此我应该使用确认(又名发布者确认)。

如果代理在所述消息写入磁盘之前崩溃,代理将丢失持久性消息。 在某些情况下,这会导致经纪人以令人惊讶的方式行事。

例如,考虑这种情况:

  • 客户端发布持久消息给持久队列
  • 客户端使用队列中的消息(注意消息是持久的并且队列持久),但还没有确认,
  • 经纪人死亡并重新启动,并且
  • 客户端重新连接并开始消费消息。
  • 此时,客户可以合理地认为该消息将再次发送。 情况并非如此:重新启动导致代理丢失消息。 为了保证持久性,客户应该使用确认。

    但是,如果使用确认,发布者在收到确认之前发生故障,并且由于某种原因(即网络故障)未将消息传递到队列中,该怎么办?

    假设我们有一个简单的REST端点,我们可以发布新的COMMENTS,并且当创建一个新的COMMENT时,我们想要在队列中发布消息。 (注意:如果我发送一个新的COMMENT消息,但最后由于回滚而未创建消息,则无关紧要)。

    CommentEndpoint {
    
      Channel channel;
    
      post(String comment) {
        channel.publish("comments-queue",comment) // is a persistent queue
        Comment aNewComment = new Comment(comment)
        repository.save(comment)
        // what happens if the server where this publisher is running terminates here ?
        channel.waitConfirmations()
      }
    
    }
    

    当服务器重新启动时,通道消失,消息永远不会传递。 我想到的一个解决方案是,重新启动后,查询库中最近的评论(类似于崩溃前最后3分钟创建的评论),并为每个评论发送一条消息并等待确认。


    你所担心的不再是RabbitMQ唯一的问题,它是一个分布式事务问题。 这个讨论提供了一个合理的轻量级解 还有更严格的解决方案,例如两阶段提交,三阶段提交等,以确保数据在真正需要时保持一致。

    链接地址: http://www.djcxy.com/p/59239.html

    上一篇: What happens if a Publisher terminates before receive ack?

    下一篇: AnyEvent::RabbitMQ issues with closed channels