如何保证大众交通中的消息接收顺序
本文关键字:消息 顺序 何保证 | 更新日期: 2023-09-27 18:35:04
我有一个有 3 个状态的传奇;初始、接收行、已完成 -
public static State Initial { get; set; }
public static State ReceivingRows { get; set; }
public static State Completed { get; set; }
当它获得 BofMessage 时,它会从初始转换为接收行(其中 Bof = 文件的开头)。在 BofMessage 之后,它会收到大量行消息,其中每个行消息描述平面文件中的一行。发送所有行消息后,将发送 EofMessage 并且状态更改为"已完成"。观察-
static void DefineSagaBehavior()
{
Initially(When(ReceivedBof)
.Then((saga, message) => saga.BeginFile(message))
.TransitionTo(ReceivingRows));
During(ReceivingRows, When(ReceivedRow)
.Then((saga, message) => saga.AddRow(message)));
During(ReceivingRows, When(ReceivedRowError)
.Then((saga, message) => saga.RowError(message)));
During(ReceivingRows, When(ReceivedEof)
.Then((saga, message) => saga.EndFile(message))
.TransitionTo(Completed));
}
这是有效的,除了有时在 BofMessage 之前会收到几个行消息!这与我发送的订单无关。这意味着消息将被接收并最终计为错误,导致它们从我最终写出它们的数据库或文件中丢失。
作为临时修复,我在此方法中添加了一个小的睡眠计时器技巧,可以完成所有发布 -
public static void Publish(
[NotNull] IServiceBus serviceBus,
[NotNull] string publisherName,
Guid correlationId,
[NotNull] Tuple<string, string> inputFileDescriptor,
[NotNull] string outputFileName)
{
// attempt to load offsets
var offsetsResult = OffsetParser.Parse(inputFileDescriptor.Item1);
if (offsetsResult.Result != ParseOffsetsResult.Success)
{
// publish an offsets invalid message
serviceBus.Publish<TErrorMessage>(CombGuid.Generate(), publisherName, inputFileDescriptor.Item2);
return;
}
// publish beginning of file
var fullInputFilePath = Path.GetFullPath(inputFileDescriptor.Item2);
serviceBus.Publish<TBofMessage>(correlationId, publisherName, fullInputFilePath);
// HACK: make sure bof message happens before row messages, or else some row messages won't be received
Thread.Sleep(5000);
// publish rows from feed
var feedResult = FeedParser.Parse(inputFileDescriptor.Item2, offsetsResult.Offsets);
foreach (var row in feedResult)
{
// publish row message, unaligned if applicable
if (row.Result != ParseRowResult.Success)
serviceBus.Publish<TRowErrorMessage>(correlationId, publisherName, row.Fields);
else
serviceBus.Publish<TRowMessage>(correlationId, publisherName, row.Fields);
}
// publish end of file
serviceBus.Publish<TEofMessage>(correlationId, publisherName, outputFileName);
}
这是一个 5 秒的睡眠计时器,是一个相当丑陋的黑客。谁能告诉我为什么我没有按照发送的顺序收到消息?如果这些消息默认为无序,我是否可以确保它们以正确的顺序发送?
谢谢!
请注意,这是从 http://groups.google.com/group/masstransit-discuss/browse_thread/thread/7bd9518a690db4bb 交叉发布的,方便起见。
您无法确保按任何顺序传递消息。您可以通过确保消费者端只有一个并发消费者来接近 MT,我仍然不会依赖这种行为(http://docs.masstransit-project.com/en/latest/overview/keyideas.html#handlers)。这将有效地使您的使用者成为单线程。