使用NService Bus发布大量消息

时间:2017-01-17 05:44:07

标签: nservicebus azureservicebus

我想使用n服务总线发布大量消息。 我找到了一个重载的Publish方法,它将消息列表作为参数。 当我尝试使用它时,它显示以下错误

  var message= new Message
                    {                           
                        Id = id,
                        Timestamp = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local),
                        PublishingStartTimestamp = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local)

                    };

                    bus.Publish(new[] { message, message});

错误:'NServiceBus.IBus.Publish(params T [])'已过时:'已移除以降低复杂性和API混淆。有关详细信息,请参阅https://github.com/Particular/NServiceBus/issues/1346。将在5.0.0版中删除。'

发布大量邮件的替代方法是什么。 我的任务是每秒发布600个事件。 有人可以帮忙吗?

提前致谢!

2 个答案:

答案 0 :(得分:7)

高音量

我不确定你的用例是什么。如果这是一致的消息流,600 msg / s转换为单个端点每天近5200万条消息。

用例

我们会对您的用例感兴趣,我们可以在我们的Google群组中公开讨论

我们也可以通过support@particular.net

与我们联系,私下这样做

作为单个或单个消息接收

如果发送这600条消息,您是否希望在接收端将它们视为单个消息?我问的原因是问题中的API是什么。它创建一个包含所有这些消息的信封。在传输上,您将看到一条物理消息。在接收端,所有消息都将作为单个接收操作进行处理。

如果这是您想要的行为,则必须创建一个包含集合(数组/列表)的消息,并将所有这些消息片段放入其中。

这个策略的好处在于你在合同中使行为更加明确。

var message = new ParentMessage();
for(int i=0;i<600;i++) message.Children.Add(new ChildFragment());
Bus.Publish(message);

传输邮件大小限制

Azure Service Bus消息在标准层上最多为256KB,在高级层上最多为1MB。如果片段包含大量数据,那么以前的解决方案可能无法使用单个大型消息。

接收上下文

在您的问题中,不清楚您是在接收消息的上下文中还是在接收上下文之外发送这些消息。每种行为都不同。

在传入的消息上下文中,发送被缓冲。在传入的消息上下文之外,消息被直接推送到传输。

批量派遣

您在NServiceBus V5或V6中使用Azure Service Bus默认情况下会缓冲。如果您在处理程序/传奇中执行发布/发送,则不会立即将消息推送到传输。

此行为的原因是为了防止“重影”消息。假设您发送了一条消息,之后您创建了第二条消息,并且在映射期间,会发生空引用异常。您是否希望第一条消息已被推送到传输中?可能不是,这是默认行为。

对于Azure Service Bus,通过执行事务范围登记,此行为也存在于V5中。如果您不希望在V5中出现此行为,请通过禁用分布式事务来禁用事务范围的使用。

异步

在V6中,API是异步的,这意味着您可以执行以下操作:

var tasks = new List<Task>();
for(int i=0;i<600;i++) tasks.Add(context.Publish(new MyEvent()));
await Task.WhenAll(tasks).ConfigureAwait(false);;

由于缓冲发送,除非创建消息正在执行IO,否则这并没有太大的区别。

如果您在接收消息上下文之外执行此操作,那么它可以提高性能。

var tasks = new List<Task>();
for(int i=0;i<600;i++) tasks.Add(messageSession.Publish(new MyEvent()));
await Task.WhenAll(tasks).ConfigureAwait(false);;

这是因为邮件会立即同时推送到传输中。

立即发送

如果您明确不希望缓冲消息,那么您可以使用立即调度。以下是V6样本。

var options = new SendOptions();
options.RequireImmediateDispatch();
var message = new MyMessage();
await context.Send(message, options).ConfigureAwait(false);

效果

您在说明中使用的API是NServiceBus V5或更早版本。在V6中,Azure Service Bus的性能得到了显着提升。

可以调整很多变量来提高性能。

对于V6中的单个端点实例,每秒发送/接收数千条消息应该不是问题。

答案 1 :(得分:4)

NServicebus支持异步发布消息:https://particular.net/blog/async-await-its-time

假设您在接收消息上下文之外,您可以在任务列表中收集所有发布任务,然后让任务与WhenAll运行异步。

另外,请确保未达到每秒天蓝色服务总线的最大消息限制。

<强>更新 请参阅Ramon Smit的答案以获得完整的答案。