2011-09-29 56 views
3

我正在寻找一些我们遇到的生产问题的帮助。什么导致了这种情况下的瓶颈?

我们有一个NServiceBus处理程序,它在处理消息时向IIS 6.0上运行的asmx(.net 2.0)Web服务发送请求,然后Web服务将第二个http请求平均发送到第三方Web服务第三方服务需要500毫秒才能响应,但我们被告知只有当11个同时请求正在进行时才会启动排队请求。

为了满足我们处理SLA的需求,我们需要每小时处理79,000条消息或每分钟处理约1300条消息。有11个请求并行处理,平均需要500毫秒,如果我们能够获得11个并发请求,每秒钟我们应该能够处理大约20条消息,这应该是可以实现的。

我们现在面临的问题是,我们无法在这些数字附近找到任何地方。我们部署的解决方案如下。我们有一项服务,每5分钟轮询一个数据库以检索一批100条新消息,它将它们发送给一个经销商,该经销商负责在两台服务器上运行的四个工作者Windows服务间的负载平衡。我会给他们打电话NsbServerA & NSbServerB。每个辅助服务都配置了2个线程,所以我们总共有8个线程。我们有两台运行asmx Web服务的服务器,我将其称为asmx1 & asmx2,ServerA向asmx1发送请求,ServerB向asmx2发送请求。

当前的吞吐量是每小时30,000条消息,每分钟约500个,每秒约8个,所以我们有一个瓶颈问题在哪里?

我已经看到这篇文章http://support.microsoft.com/default.aspx?scid=kb;en-us;821268这似乎表明如果您想对同一个webservice进行多个并发调用,您必须调整IIS 6.0过程模型。从文章

报价: “如果你正在一个Web服务调用从每个ASPX页面一个IP地址,Microsoft建议您使用以下配置设置: 设置maxWorkerThreads参数的值和maxIoThreads参数到100 设置MAXCONNECTION参数的值,以12 * N(其中N是你有CPU的数量)。 设置minFreeThreads参数的值,以88 * N和minLocalRequestFreeThreads参数to76 * N。 将minWorkerThreads的值设置为50.请记住,默认情况下minWorkerThreads不在配置文件中,您必须添加它。“

如果任何人都可以阐明发生了什么或解决方案是什么,我会非常感激。

感谢,

查理

+2

Downvoter,请与OP分享他需要纠正的内容,以避免downvote。 –

+0

您是否单独测量每个组件的吞吐量?这可以使用每个组件的存根/模拟服务来完成。 – Oded

+2

我在任何地方都看不到编程问题。 – bmargulies

回答

2

一个可能的可能性:

的ServicePointManager,通过它你所有的.NET Web请求路由,具有每个对象的两个并发连接的默认。见ServicePointManager.DefaultConnectionLimit

因此,如果您的第三方Web服务平均需要500毫秒的响应时间,则单个服务器每秒只能对该服务执行四次请求。 (即每500毫秒两个并发请求)。

乘以两台服务器,你会得到每秒8条消息。

尝试设置ServicePointManager.DefaultConnectionLimit = 4;当您启动您的程序,并查看是否增加您的吞吐量。

+0

我会放弃并让你知道 –

0

听起来像它可能是很多事情。

  1. 您是否使用市售的标准版NServiceBus?没有你的处理程序将工作单线程。
  2. 您的中档Web服务是异步的吗?如果第二次服务往返是同步进行的,则线程将被捆绑并且无法处理传入的请求。
  3. 您是否配置了足够的工作线程来处理传入的请求? 更新:请参阅本页http://msdn.microsoft.com/en-us/library/ff647787.aspx#scalenetchapt06_topic9(“表6.1:推荐用于减少争用的线程设置”),以获得高吞吐量建议。您应该查看的设置是minFreeThreads,maxconnection,maxWorkerThreads和minWorkerThreads。

如果你不能在没有大规模优化的情况下无法可靠地达到这个目标,我会紧张地承诺每秒处理20条消息的吞吐量SLA。

也可能是一个愚蠢的问题,但为什么你不能直接从你的消息处理程序调用远程服务?

+0

我们正在使用版本2。0,它早于具有单线程调节的商业版本。没有中间层webservice不是异步的,所以这可能是问题,我可以部署这个服务的多个实例来查看吞吐量是否增加。如果事实证明是这个问题,你知道是否将它改为异步可以解决问题? 3这个配置在哪里? 不是一个愚蠢的问题,这可能会成为最好的解决方案,但这意味着维护两套代码来完成同样的事情,中间层服务被其他服务所使用,有些是第三方。 –

+0

我想我们也可以修改中间层web服务来简单地创建NServiceBus消息并将其传递给NSB分发服务器进行处理。那么我们只会有一段代码要维护。我认为NServiceBus网关可以用这种方式使用。 –

+0

请参阅更新到我原来的答案... –

0

我建议单独测试系统的每一层。

具体而言,首先将数据库层折扣为一个问题。我会将一些简单的集成式单元测试放在一起,这些测试可以执行数据库的峰值吞吐量,理想情况下可以使用类似于Parallel.ForEach的东西同时运行几百个线程。

然后向上移动一层并使用类似存根的东西来“模拟”数据库调用并验证服务层的行为是否应该如此。

然后至少你将能够缩小效率低下并处理它们。