【问题标题】:Does ActiveMQ guarantee message delivery?ActiveMQ 是否保证消息传递?
【发布时间】:2020-12-03 04:32:48
【问题描述】:

当我们使用ActiveMQ 时,我们可以信任ActiveMQ 服务器的可靠性。例如在开发非实时软件时(不需要立即发送数据。但应该发送)。我们可以信任activeMQ 作为确认消息传递的可靠来源吗?例如,我正在从生产者那里发送一个 xml 文件。将该文件发送到ActiveMQ 确认 ActiveMQ 交付。那么我可以信任ActiveMQ 并删除 xml 的本地副本吗?

编辑

当消息到达 ActiveMQ 服务器时,它是可靠的。我们如何确保生产者服务器链接的可靠性。如果生产者是 java SE 应用程序。 ActiveMQ 客户端如何处理这些场景

  • 在准备发送数据时强制关闭应用程序。
  • 发送消息时出现网络故障。

【问题讨论】:

    标签: activemq


    【解决方案1】:

    如果您使用事务和持久传递(如果您使用 JMS,则几乎是默认值)发送到 ActiveMQ 并且事务提交成功 - 是的。然后 ActiveMQ 将消息保护在持久存储(通常是磁盘)上。

    然后,当然,磁盘可能会崩溃,人为错误和地震可能会袭击您,但除此之外,消息正常。

    【讨论】:

    • 感谢@Petter Broker 消费者连接是可靠的。在这种情况下,我们如何确保生产者到代理的可靠性[生产者和客户端之间的网络故障,客户端应用程序在准备发送消息时强制停止。
    • 根据您的客户端/框架,您将在发送期间的某个时间点进行提交。如果成功,您的消息是安全的,您可以继续删除旧数据。
    【解决方案2】:

    ActiveMQ 绑定到 JMS 规范,该规范要求 JMS 提供者在默认情况下必须保证“持久”消息的传递。这种保证确实伴随着沉重的性能代价,因为代理必须在向生产者确认消息之前将消息安全地保存在其消息存储中。此保证不需要本地 JMS 事务,但可用于将消息批量发送到代理,这是克服沉重性能代价的一种方法。

    【讨论】:

      【解决方案3】:

      我建议生产者在客户端确认它已收到消息之前不能丢弃 XML 消息。仅确认 ActiveMQ 服务器已收到它是不够的,因为在客户端收到之前,该消息没有任何价值。

      因此,为此,我会发现某种接收确认是一个好方法。一个简化的系统可能会像这样工作......

      初始设置

      首先,创建两个主题:“messages”和“message-receipts”。

      接下来,将 Producer 设置为发布到 'messages' 主题,并订阅 'message-receipts' 主题。 Producer 还应该能够维护所有已发送但尚未确认的消息的列表。

      此外,您的客户端将订阅“消息”主题,并发布到“消息收据”主题。

      发布消息

      要发布消息,Producer 会首先生成一个 XML 消息,并给它一个可以识别消息的唯一 ID。然后它将在“消息”主题上发布。

      然后,客户端将看到有关“消息”主题的消息。然后它必须转身并发布一个“message-receipts”响应,其中将包含收到的消息的 ID。

      最后,Producer 将看到“message-receipts”消息,并可以通过将 message-receipt ID 与尚未确认的消息列表进行比较来确认消息已发送。确认后,该消息将从“已发送但尚未验证”列表中删除。

      处理未收到的消息

      如果一段时间内没有收到消息,生产者可以重新发送消息。

      【讨论】:

        【解决方案4】:

        是的,ActiveMQ 是基于 JMS 的消息代理,其核心旨在保证消息的可靠传递。为了更好地理解这一点,让我们考虑通过系统的消息路径,即从生产到消费。

        消息通常分两跳传递。第一跳是消息从生产者传输到消息代理上的目的地的地方,在本例中为 ActiveMQ。在第二跳中,消息从代理上的物理目的地传输到消费者。

        在此过程中,只有三种方式可以使消息在其路径中丢失。第一个是当它从生产者移动到消息代理时。第二个可能的丢失点在代理内存中,最后是在从代理到消费者的路径上。

        ActiveMQ 使用两种机制来ensure messages are not lost 以三种方式中的任何一种方式。首先是代理将所有消息存储在高度持久的数据存储中。如果在消息成功投递之前系统中断或者broker内存出现故障,broker仍然可以在恢复后重新获取消息并重试操作。

        其次,ActiveMQ 使用确认和事务来确保消息的生产和消费都成功。即使使用这两种方法,也可能会出现消息未成功传递的情况。例如,当用于消费消息的事务会话被回滚时。发生这种情况时,消息将返回到队列并重新传递。

        ActiveMQ 提供了两种方法来处理返回到队列并重新传递但未成功的消息。这些是延迟重新投递和死信地址。

        对于延迟重新传递,消息会延迟一段时间,以允许消费者从瞬时故障中恢复并防止网络或系统过载。这是一个示例,展示了如何在地址设置配置中定义延迟重新投递。

        <!-- delay message redelivery for 5 seconds -->
        <address-setting match="exampleQueue">
           <!-- default is 1.0 -->
           <redelivery-delay-multiplier>1.5</redelivery-delay-multiplier>
           <!-- default is 0 (no delay) -->
           <redelivery-delay>5000</redelivery-delay>
           <!-- default is 0.0) -->
           <redelivery-collision-avoidance-factor>0.15</redelivery-collision-avoidance-factor>
           <!-- default is redelivery-delay * 10 -->
           <max-redelivery-delay>50000</max-redelivery-delay>
        </address-setting>
        

        对于死信地址,未成功投递的消息从队列中移除并发送到死信地址。代理不会尝试重新传递此类消息,而是将它们置于系统管理员可以访问并采取行动的队列中。

        下面是一个简单的死信地址配置。

        <!-- undelivered messages in the Queue are sent to a dead letter address
        after 3 unsuccessful redelivery attempts -->
        <address-setting match="exampleQueue">
           <dead-letter-address>deadLetterAddress</dead-letter-address>
           <max-delivery-attempts>3</max-delivery-attempts>
        </address-setting>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-06-28
          • 2016-11-18
          • 2016-08-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多