我有一个biztalk业务流程处理单个消息。此消息实际上是批量消息。大多数情况下,批量大小n
很小(<1.000)但偶尔会有非常大的批次(> 50.000)。我们也有很高的消息吞吐量。
业务流程根据批量大小采用线性O(n)
系统内存量,我通过观察得知单个服务器在系统用完之前可以并行处理累计批量大小〜250k内存,只返回OutOfMemoryExceptions
。 (这将杀死BizTalk主机实例,并且业务流程将在另一台主机上启动,最终将再次中断,使我们的BizTalk组处于破碎状态,目前只能通过手动干预恢复)
小批量是常见的,大批量是罕见的,但如果同时存在多个批次则是致命的。
我事先知道批量大小,所以我可以告诉biztalk。但我认为没有办法与节流互动。当限制检测到系统内存不足时,已经太晚了。
我是否必须在biztalk之上建立自己的排队和调度以实现我的目标?
我们当前的解决方案是使用值为8的信号量,并且每个大消息n>1000
在允许开始处理之前需要获取信号量槽。前几天我们有一个边缘案例,即使这个太多了。我们减少了8到4来解决这个问题,但现在,我们明显影响了总体吞吐量。
欢迎任何想法或提示!
答案 0 :(得分:1)
XmlDocument
。它会进一步加剧你的记忆问题。这里肯定更喜欢XmlReader
。但是,我仍然会尝试在您的业务流程之外移动处理。即使您可以在从业务流程调用的.NET组件中使用流式传输,您仍然可以使用长时间运行并消耗大量内存的业务流程实例,应尽可能避免这种情况。因此... 避免让业务流程获取大型消息。如果您可以将架构标记为信封架构,则可以使用OOB XmlDisassembler
来解除消息;如果没有,您可能需要创建一个自定义反汇编程序组件来进行debatching(只记得向原始创建的消息中提升/写入正确的上下文属性)。如果您在管道中使用某些流技术(请参阅https://www.microsoft.com/en-us/download/details.aspx?id=20375),则可以大大减少内存占用并在那里获得更大的控制权。再次,使用XmlReader
来实际解析和分发消息(这不应该是非常困难的 - 请查看ReadToFollowing
和ReadSubTree
,如此Splitting large xml files in to sub files without memory contention)。您可能会在业务流程而不是管道组件中执行此操作,但在管道组件中,应该更容易控制内存使用。如果您需要将消息重新关联在一起,您还可以考虑宣传批量ID之类的内容。
如果获得大批量,您仍需要限制并发编排的数量;你可以这样做,理查德·塞罗特建议here,它使用多个与实例ID相关的车队,以防止一次运行太多。或者,您可以在接收形状上使用有序传递(请参阅MSDN),这可能是我的首选选项,因为它需要的工作量大大减少,并且不会遇到围绕车队可能出现的僵尸消息的问题。 / p>
基本上:尽可能地考虑小而精益,BizTalk会更快乐。 BizTalk更愿意在一分钟内处理1000条小消息而不是1条非常大的消息。