【问题标题】:BizTalk: how to limit number of connections to a wcf service?BizTalk:如何限制与 wcf 服务的连接数?
【发布时间】:2010-08-28 15:23:08
【问题描述】:

我开发了一个 BizTalk 应用程序,它接收一个包含一堆消息的文件作为输入。我使用 BizTalk XML 反汇编程序组件在单独的消息中“分批”文件。这些消息中的每一个都由一个编排从 MessageBox 中提取,该编排转换消息并调用 wcf 服务。

我现在遇到的问题是每批包含 1000 条消息,而这 1000 条消息似乎都同时调用了 wcf 服务。 wcf 服务被这些消息“轰炸”,并且被配置为仅并行处理 10 条消息(每个调用都必须处理数据并将数据放入数据库)并将一堆“太忙”异常返回给 BizTalk。我将 wcf 适配器配置为在 1 分钟后重试连接。

最终的结果是 BizTalk 首先对消息进行分批,然后用所有 1000 条消息轰炸 wcf 服务,得到一堆“太忙”的异常,然后无所事事地等待,直到 1 分钟过去,然后再次轰炸它,等等。

如果我可以将 BizTalk 配置为打开最多 10 个到该特定 wcf 服务的连接,则处理效率会更高,但据我所知,这是不可能的。 (wcf 服务配置为使用 net.tcp。)

我已经用几种不同的方式尝试了主机的节流设置,但要么没有帮助,要么让应用程序变得难以忍受。此外,BizTalk 中的节流似乎是以一种方式实现的,它首先轰炸服务,然后注意到它正在轰炸,然后等待一段时间什么都不做,然后解除油门并再次开始轰炸。将请求/消息涓涓细流似乎要好得多,以便它们在时间上更均匀地分布。例如,我想将 WCF 适配器配置为每秒最多接收 4 条消息。现在可能的限制是这样的:在 5 秒的滑动窗口中,如果有超过 20 条消息,我希望激活限制。但这不一样,因为它允许“爆发”效果。

有什么想法可以提高吞吐量吗?

【问题讨论】:

  • 这根本不是一个好的解决方案,但如果您遇到生产故障问题,您可以使用以下方法。在发送端口高级选项中设置“Ordered Delivery”。您一次只能通过端口收到一条消息。它非常慢,但它可以让你在重写时移动。

标签: wcf biztalk throttling biztalk-2009


【解决方案1】:

使用BizTalk singleton pattern。这很丑陋。但是 BizTalk 优雅的架构在遇到现实世界时会产生丑陋。

【讨论】:

    【解决方案2】:

    对于 SOAP、HTTP 和基于 HTTP 的 WCF 适配器,您可以使用 connectionManagement 设置并限制那里的连接数。您可以准确指定每个 BizTalk 主机实例允许的并发连接数。 Setting SOAP, HTTP, and HTTP-based WCF Adapters Concurrent Connections

    注意事项:

    1. 这限制了每个主机实例的连接数。因此,如果您在不同的主机上有多个发送端口,或者每台主机有多个主机实例,那么建立的连接总数仍然可以超过这个数量。

    2. 这仅适用于 SOAP、HTTP 和基于 HTTP 的 WCF 适配器。如 rvdginste 所述,不适用于其他 WCF 适配器

    【讨论】:

    • 如果我没记错的话,我确实检查了该选项,但注意到它不适用于通过“net.tcp”访问的 wcf 服务。
    【解决方案3】:

    这个问题已经有一年多了,但我只想添加一个答案,以防有人遇到同样的问题。

    我尝试使用 BizTalk 主机的限制配置。这没有帮助。我实际上并没有尝试使用单例模式,因为那是我不想要的:我们创建了一个强大的面向服务的架构,可以轻松地并行处理多个消息,我不想通过引入单例模式来完全撤消它.

    那我最后做了什么?首先,我再次考虑了实际需要什么:我们需要处理一堆文件,每个文件都包含 1000 条消息。处理文件中消息的顺序并不重要。处理文件的顺序很重要。通常,我们应该先处理文件 1,然后处理文件 2,然后处理文件 3,以此类推。不过没有那么严格,顺序只是文件的范围,例如,首先要处理范围 1-5,然后处理范围 6-8,但在一个范围内,文件的顺序并不重要。所以这些就是要求。

    我改变的第一件事是,我不是一次处理一条消息,而是将服务改为接受一组消息,这样我一次可以处理一个文件。通过一次处理 1 个文件,只有 1 次调用 WCF 服务,其优点是 BizTalk 和 WCF 服务之间的闲聊少了很多。但是请注意,这会使 WCF 服务端的代码更加复杂,因为每条消息仍然必须独立于其他消息进行处理(使错误处理更加复杂)。如果我们设法一次处理有限数量的文件,我们也可以避免太忙的错误。

    除了消息的实际处理之外,WCF 服务还提供调用来“注册”文件处理。这是服务器端的代码,用于检查当时是否可以处理文件:它考虑了文件的顺序,并确保只有在前一个文件(范围)已经存在时才能注册文件(范围)处理。这些注册调用尝试在内部等待的循环中注册文件(范围)。该调用尝试注册文件,如果不被接受,它会等待然后重试。我不是很喜欢这个解决方案,但它确实有效。

    所以最后我有一个考虑文件范围顺序的解决方案,旁边有一个关于可以并行处理多少个文件的配置。这意味着我不再遇到任何太忙的错误。对我的解决方案并不完全满意,但它确实有效并且非常稳定。过去一年它一直运行没有问题。

    【讨论】:

      【解决方案4】:

      BizTalk 中的主机限制状态是 BizTalk 本身可用性的一种自我保护机制 - 我不会轻易更改这些。

      与 Igal 的单例想法一样,您可以对 BizTalk 做一些肮脏的事情,以防止它使用 WS 调用使您的应用程序过载,但恕我直言,这样做最终可能会损害 BizTalk 服务器的可伸缩性。似乎对您的应用程序的同步调用可能是问题 - 可能考虑改为使用 MSMQ 异步执行此操作?

      但是,如果您保持同步 wcf,您还可以查看 these knobs 以获取发送主机上的 WCF 适配器(如果还没有的话,我认为您需要转到 WCF-Custom 适配器)

      【讨论】:

        【解决方案5】:

        我已经多次使用Instance Controller 模式,它似乎运行良好。这个想法是您将真实消息包装在编排的有效负载中。当需要调用您的服务时,您改为将其传递给一个编排,如果正在运行的编排过多,该编排就会脱水。这是一个简单的概念,而且效果很好。

        我会说这个博客非常过时.. 但这个想法很有效。

        【讨论】:

          猜你喜欢
          • 2016-05-20
          • 2012-02-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-19
          • 2016-01-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多