拆分要发送到Azure Service Bus的批处理消息

时间:2017-06-27 11:57:14

标签: c# azure azureservicebus

我们假设我有一批List<BrokeredMessage>条消息要批量发送到Azure Service Bus。

集合大小是任意的,因此所有组合消息的总大小可能超过Service Bus强加的256k的限制。如何以最佳方式将其分成较小的块?

这项任务似乎很简单,但似乎并非如此:在我尝试发送之前,每个BrokeredMessage的大小都是未知的。 Size属性只返回消息体的大小,没有标题和其他开销。

如果我尝试发送每条250字节的1000条消息,我将获得MessageSizeExceededException。问题是现在我甚至无法重试,因为消息已被消费,所以我必须重新创建所有BrokeredMessage

因此,我现在看到的唯一方法是在发送大量小消息时对批量大小保守,这可能会花费我一些吞吐量。

是否有更可靠和/或更干净的方式?

2 个答案:

答案 0 :(得分:2)

  

因此,我现在看到的唯一方法是在发送大量小消息时对批量大小保守,这可能会花费我一些吞吐量。

不仅需要吞吐量,还需要可靠性。当使用MessageSender.SendBatchAsync()时,所有消息都作为原子操作发送,并且一起成功或失败。

  

是否有更可靠和/或更干净的方式

使用TransactionScope包装所有发送将会达到同样的效果,但您不会再批量发送邮件。

如果您仍然想要发送批次,请确保您不会遇到大小/数量问题,就像建议您可以将您的发送分块一样。不幸的是,Size属性对于大小估计是不可取的。它会在序列化之前报告正文。除非使用Stream,否则不会应用序列化。然后,事件仍然是您的尺寸将被标准和自定义属性扭曲。当重新安排WindowsAzure.ServiceBus的文档时,BrokeredMessage的MSDN API文档中丢失了以下注释:

  

要获得BrokeredMessage大小的准确值,您应该在BrokeredMessage上完成发送/接收操作后读取Size属性。

我根据估计的尺寸采取了分块的方法。估计的大小基于某个填充百分比来膨胀消息的大小,期望平均消息将小于填充大小。基于字符串的属性的加号和平均假定大小。在这个blog post中,我已经提出了估算单个邮件大小的想法,该邮件大小将用于计算可能作为批处理的块大小。

答案 1 :(得分:1)

为了完成Sean的回答,Paolo Salvatori为MessageSender类编写了一些扩展方法,你可以在这里找到:

基本上,它会遍历所有邮件并批量处理,因此大小不会超过最大批量大小。

我遇到了一些问题,因为BrokeredMessage.Size没有考虑Properties的{​​{1}}。我稍微修改了他的版本以添加BrokerMessage大小:

Properties