BizTalk:如何限制与 wcf 服务的连接数?
我开发了一个 BizTalk 应用程序,该应用程序接收包含一堆消息的文件作为输入。我使用 BizTalk XML 反汇编器组件在单独的消息中“反批”文件。其中每条消息均由编排从 MessageBox 中获取,该编排转换消息并调用 wcf 服务。
我现在遇到的问题是,每个批次包含1000条消息,而这1000条消息似乎都同时调用了wcf服务。 wcf 服务被这些消息“轰炸”,并且被配置为仅并行处理 10 条消息(每个调用都必须处理数据并将数据放入数据库),并向 BizTalk 返回一堆“太忙”异常。我将 wcf 适配器配置为 1 分钟后再次重试连接。
最终的结果是BizTalk首先将消息分批,然后用所有1000条消息轰炸wcf服务,得到一堆“太忙”异常,然后什么都不做等待,直到1分钟过去,然后再次轰炸,如此在。
如果我可以将 BizTalk 配置为打开与该特定 wcf 服务的最多 10 个连接,处理会更加高效,但据我所知,这是不可能的。 (wcf 服务配置为使用 net.tcp。)
我已经尝试了几种不同方式的主机限制设置,但要么没有帮助,要么使应用程序速度慢得难以忍受。另外,BizTalk 中的节流似乎是通过以下方式实现的:首先轰炸某个服务,然后注意到它正在轰炸,然后等待一段时间什么也不做,然后抬起油门并再次开始轰炸。滴流式发送请求/消息似乎要好得多,这样它们就可以在时间上更加均匀地传播。例如,我想将 WCF 适配器配置为每秒最多接收 4 条消息。现在可能的限制是这样的:在 5 秒的滑动窗口内,如果消息超过 20 条,我希望激活限制。但这不一样,因为它允许“爆发”效果。
有什么想法可以提高吞吐量吗?
I developed a BizTalk application that receives as input a file that contains a bunch of messages. I use the BizTalk XML disassembler component to 'debatch' the file in sepereate messages. Each of those messages is picked up from the MessageBox by an orchestration that transforms the message and calls a wcf service.
The problem I am experiencing now is that each batch contains 1000 messages, and that those 1000 messages all seem to call the wcf service at once. The wcf service is "bombed" by those messages and is configured to process only 10 messages in parallel (each call has to process data and put data in a database) and returns a bunch of "Too Busy" exceptions back to BizTalk. I configured the wcf adapter to retry the connection again after 1 minute.
The end result is that BizTalk first debatches the messages, then bombs the wcf service with all 1000 messages, gets a bunch of "Too busy" exceptions, then waits while doing nothing, until 1 minute is passed, then bombs it again, and so on.
The processing would be much more efficient if I could configure BizTalk to open max 10 connections to that specific wcf service, but as far as I know, this is not possible. (The wcf service is configured to use net.tcp.)
I did already try the throttling settings of the host in several different ways, but either it is not helping, or it is making the application unbearable slow. Also the throttling in BizTalk seems to be implemented in a way that it first bombs a service, then notices that it was bombing, then waits a while doing nothing, and then lifts the throttle and start bombing again. It seems much better to trickle the requests/messages, so that they are much more evenly spread in time. I would like to configure the WCF adapter to receive max 4 messages per second for example. The throttling that is possible now says something like: over the sliding window of 5 seconds, i want throttling to be activated if there are more than 20 messages. But that is not the same, because it allows a "burst" effect.
Any ideas how i can improve throughput?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用 BizTalk 单例模式。这太丑了。但 BizTalk 优雅的架构在与现实世界相遇时却显得丑陋。
Use the BizTalk singleton pattern. This is ugly. But BizTalk elegant architecture create ugliness when it meets the real world.
BizTalk 中的主机限制状态是 BizTalk 本身可用性的自我保护机制 - 我不会轻易更改这些。
与 Igal 的单例想法一样,您可以对 BizTalk 做一些肮脏的事情,以防止它通过 WS 调用使您的应用程序过载,但恕我直言,这样做最终可能会损害 BizTalk 服务器的可扩展性。看来对您的应用程序的同步调用可能是问题所在 - 可能会考虑更改为使用 MSMQ 异步执行此操作?
但如果您保持同步 wcf,您还可以查看 这些发送主机上 WCF 适配器的旋钮(我认为您需要移至 WCF 自定义适配器(如果还没有))
The host throttling states in BizTalk are a self preservation mechanism for the availability of BizTalk itself - I wouldn't change these lightly.
As with Igal's singleton idea, you can do dirty things to BizTalk to prevent it overloading your app with WS calls, but IMHO ultimately you might hurt your BizTalk server's scalability by doing this. It would seem that synchronous calls to your application might be the issue - possibly look at changing to doing this Asynchronously using MSMQ?
But if you stay synchronous wcf, you can also look at these knobs for the WCF adapter on your send Host (I think you'll need to move across to the WCF-Custom adapter if not already)
对于 SOAP、HTTP 和基于 HTTP 的 WCF 适配器,您可以使用连接管理设置并限制那里的连接数量。您可以准确指定每个 BizTalk 主机实例允许的并发连接数。
设置 SOAP、HTTP 和基于 HTTP 的 WCF 适配器并发连接< /a>
注意:
这限制了每个主机实例的连接数量。因此,如果您在不同的主机上有多个发送端口,或者每个主机有多个主机实例,则所建立的连接总数仍可能超过此数量。
这仅适用于SOAP、HTTP 和基于 HTTP 的 WCF 适配器。不适用于 rvdginste 指出的其他 WCF 适配器
For SOAP, HTTP, and HTTP-based WCF adapters you could use the connectionManagement settings and limiting the number of connections there. You can specify exactly how many concurrent connections each BizTalk host instance is allowed.
Setting SOAP, HTTP, and HTTP-based WCF Adapters Concurrent Connections
Notes:
This limits the number of connections per Host Instance. So if you either have multiple send ports on different hosts or you have a multiple host instances per host then the total number of connections made can still exceed this number.
This is only for SOAP, HTTP, and HTTP-based WCF adapters. Not for other WCF adapters as noted by rvdginste
这个问题已经有一年多了,但我只是想添加一个答案,以防有人遇到同样的问题。
我尝试使用 BizTalk 主机的限制配置。这没有帮助。我实际上并没有尝试使用单例模式,因为这是我不想要的:我们创建了一个强大的面向服务的架构,可以轻松地并行处理多个消息,并且我不想通过引入单例模式来完全撤销这一点。
那我最后做了什么呢?首先,我再次考虑了实际需要的内容:我们需要处理一堆文件,每个文件包含 1000 条消息。文件内消息的处理顺序并不重要。文件处理的顺序很重要。通常,我们应该先处理文件 1,然后处理 2,然后处理 3,依此类推。然而,并不那么严格,顺序仅针对文件范围,例如,必须首先处理范围1-5,然后处理范围6-8,但在范围内,文件的顺序并不重要。这就是要求。
我更改的第一件事是,我不再一次处理 1 条消息,而是更改服务以接受一组消息,以便我可以一次处理 1 个文件。通过一次处理 1 个文件,仅对 WCF 服务进行 1 次调用,其优点是 BizTalk 和 WCF 服务之间的闲聊减少了很多。但请注意,这会使 WCF 服务端的代码更加复杂,因为每个消息仍然必须独立于其他消息进行处理(使错误处理更加复杂)。如果我们设法一次处理有限数量的文件,我们还可以避免“太忙”错误。
除了实际的消息处理之外,WCF 服务还提供“注册”文件处理的调用。这是服务器端的代码,用于检查当时是否可以处理文件:它考虑文件的顺序并确保只有当前一个文件(范围)已经存在时才能注册文件(范围)已处理。这些寄存器调用尝试在循环中注册一个文件(范围),并在内部等待。该调用尝试注册文件,如果未接受,则等待然后重试。我不太喜欢这个解决方案,但它确实有效。
所以最后我有一个解决方案,它考虑了文件范围的顺序,旁边有一个关于可以并行处理多少个文件的配置。这意味着我不会再遇到任何太忙的错误。对我的解决方案并不完全满意,但它确实有效并且非常稳定。去年以来,它一直运行没有出现任何问题。
This question is already over a year old, but I just want to add an answer in case someone has the same problem.
I tried playing with the throttling configuration of the BizTalk host. This did not help. I did not actually try to use the singleton pattern, because that is something I do not want: we created a powerful service oriented architecture that can easily process several message in parallel, and I do not want to completely undo that by introducing a singleton pattern.
So what did I end up doing then? First I considered again what is actually required: we need to process a bunch of files that each contain 1000 messages. The order in which a message inside a file is processed, is not important. The order in which files are processed, is important. Normally, we should process first file 1, then 2, then 3, and so on. However, it is not that strict, the order is only on ranges of files, e.g., first range 1-5 has to be processed, then range 6-8, but within a range, the order of the files is not important. So those were the requirements.
The first thing that I changed, is instead of processing 1 message at a time, I change the service to accept a collection of messages, so that I can process 1 file at a time. By processing 1 file at a time, there is only 1 call to the WCF service, which has the advantage that there is a lot less chit-chat between BizTalk and the WCF service. Note however, that this makes the code on the WCF service side more complicated because each message still has to be processed independently of the others (makes error handling more complex). If we manage to process a limited number of files at once, we can also avoid the too busy error.
Next to the actual processing of messages, the WCF service also provides calls to "register" the processing of a file. This is code on the server side that checks whether a file can be processed at that time: it takes into account the order of the files and makes sure that a file (range) can only be registered when the previous file (range) is already processed. These register calls try to register a file (range) in a loop with a wait inside. The call tries to register the file, if it is not accepted, it waits and then tries again. I don't really like this solution, but it works.
So in the end I have a solution that takes into account the order of file ranges, and next to that has a configuration on how many files can be processed in parallel. This means that I don't get any too busy errors anymore. Not completely satisfied with my solution, but it does work and is very stable. It has been running without problems for the past year.
我已经使用了 实例控制器模式很多次,它似乎工作得很好。这个想法是将真正的消息包装在编排的有效负载中。当需要调用您的服务时,您可以将其传递给一个编排,如果运行的编排过多,该编排就会脱水。这是一个简单的概念,而且效果很好。
我会说这个博客非常*过时..但这个想法是有效的。
I have used the Instance Controller pattern many times and it seems to work well. The idea is you wrap your real message in a payload of an orchestration. When it is time to call your service you instead pass it to an orchestration that dehydrates if too many orchestrations are running. Its a simple concept and it works well.
I will say the blog is very* dated.. but the idea works.