假设我有一个消息集合List<BrokeredMessage>
,我希望将其批量发送到Azure服务总线。
集合大小是任意的,因此所有消息的总大小可能超过Service Bus施加的256 k限制。如何以最佳方式将其拆分为较小的块?
这项任务看似简单,但似乎并非如此:每个BrokeredMessage
的大小在我尝试发送它之前是未知的。Size
属性只返回消息正文的大小,没有标题和其他开销。
如果我尝试发送1000条消息,每条消息的主体为250字节,我将得到MessageSizeExceededException
,问题是现在我甚至不能重试,因为消息已经被使用,所以我必须重新创建所有的BrokeredMessage
。
因此,我目前看到的唯一方法是在发送大量小消息时对批处理大小非常保守,这可能会消耗一些吞吐量。
是否有更可靠和/或更干净的方法?
3条答案
按热度按时间lvmkulzt1#
因此,我目前看到的唯一方法是在发送大量小消息时对批处理大小非常保守,这可能会消耗一些吞吐量。
这不仅会消耗吞吐量,而且会消耗可靠性。当使用
MessageSender.SendBatchAsync()
时,所有消息都作为一个原子操作发送,并且一起成功或失败。是否有更可靠和/或更干净的方法
使用
TransactionScope
Package 所有的发送将达到相同的效果,但是您将不再以批处理的形式发送消息。如果你仍然想发送批 * 和 * 确保你不陷入大小/计数问题,就像建议你可以分块你的发送。不幸的是,
Size
属性是一个大小估计不去。它报告正文**之前 * 序列化。除非使用Stream
,然后序列化没有应用。然后事件,标准属性和自定义属性仍然会扭曲您的大小。重新排列WindowsAzure. ServiceBus的文档时,BrokeredMessage
的MSDN API文档中丢失了以下注解:若要获取BrokeredMessage大小的准确值,应在完成对BrokeredMessage的发送/接收操作后读取Size属性。
我已经采取了一种基于估计大小的分块方法。估计大小是基于一定的填充百分比来膨胀消息的大小,预计平均消息将小于填充大小。加上基于字符串的属性的平均假定大小。在这个blog post中,我'我已经阐述了估计单个消息大小的思想,该消息大小将用于计算可以作为批处理发出的块大小。
pkwftd7m2#
为了完成Sean的回答,Paolo Salvatori为
MessageSender
类编写了一些扩展方法,您可以在此处找到:基本上,它会迭代所有消息并对其进行批处理,因此大小不会超过最大批处理大小。
我遇到了一些问题,因为
BrokeredMessage.Size
没有考虑BrokerMessage
的Properties
。我稍微修改了他的版本,添加了Properties
大小:xuo3flqw3#
在current library中,
ServiceBusMessageBatch
类有一个方法,允许您查看添加消息是否会超过批处理大小,允许您编写如下内容...