3

我正在处理从现场设备接收消息的情况。这些消息已标记有序列号,我需要按原始顺序处理这些消息。消息很少会丢失但并非不可能,因此我需要一个 to 机制来处理它。

我的实现是基于 NServiceBus 构建的,并且我正在使用“HandleCurrentMessageLater”功能将消息弹出到队列的后面,以防消息被乱序接收。

如果我最终收到序列中的下一条消息,这样我就可以处理积压的工作,这很好用。

在这种情况下,我必须有哪些选项来处理丢失的消息?我的第一反应是实现某种老化算法,该算法会在一定次数的失败尝试或类似情况后增加序列号,但是必须这样做的复杂性有点令人难以置信。

有没有人遇到过类似的问题并愿意分享他们是如何解决的?

谢谢

4

3 回答 3

2

在我看来,这是您需要业务投入的东西。是否有时间限制,在此之后可以假定该消息不可撤销地丢失?如果是这样,在这种情况下应该采取哪些商业行动?如果最终收到该消息但在超时之后会发生什么?

你可以用 Saga 来实现这些情况。如果消息到达并且不按顺序,那么您仍然会调用 HandleCurrentMessageLater,但您也会请求超时,以便如果在业务批准的超时后这些条件仍然成立,那么补偿操作可以运行,其余的可以处理备份的消息。

或者,替代解决方案可能是可能的。您说您需要按原始顺序处理消息。您不会详细介绍这对现实生活的影响,但这听起来像是高级业务需求,而不是技术需求。换句话说,这就是企业希望看到的方式,但不一定是它真正发生的方式。也许您可以正常处理有序消息,并增加一个值,该值指示收集的数据对哪个序列号有效。如果消息无序到达,它们仍然可以被软处理,但序列号不会增加。

所以基本上你会收到消息 1-5 并正常处理它们。然后您收到 7-10(已跳过 6 个)并处理它们,但 ValidSequenceNumber 仍为 5。然后当 #6 到达时,您对其进行处理,采取任何补偿措施以赶上,此时 ValidSequenceNumber 为 10。 Saga 也是实现这种逻辑的理想人选。

于 2013-01-03T14:28:26.560 回答
1

在使用 NSB sagas 时,David Boike 有正确的答案。我想添加另一个选项。如果消息是在短时间内生成的,则设备可以使用 NSB 功能将多个逻辑消息批处理到一个传输消息中。只需使用需要多个消息参数的SendorPublish重载。IBus这些批次保证按顺序处理。

于 2013-01-04T08:40:41.757 回答
0

如果您确实需要可靠地传递所有消息并且您的传输通道不可靠,那么您将需要一个确认和重传机制。这可能如下所示。

正常流量:

  1. 发送消息后,客户端会临时存储消息,以便在需要时能够重新传输。
  2. 成功按顺序传输后,服务器向客户端发送确认消息,包括序列号。
  3. 收到 ACK 后,客户端从其临时消息存储中删除相应的消息。

丢失的消息:

  1. 检测到失序条件后,服务器向客户端发送重传消息,其中包括最后成功接收到的消息的序列号。
  2. 客户端重新发送最后收到的消息之后的所有消息。

这显然需要双向通信,具有从服务器到客户端的传输通道。

对于保证按序传输的 TCP 协议,这个问题已经得到了深入的解决。您可能想查看 TCP 重传内部结构。

于 2013-01-03T15:48:13.360 回答