这种情况下是什么导致了瓶颈?

3
我需要帮助解决一个生产问题。
我们有一个NServiceBus处理程序,当它处理消息时,会向运行在IIS 6.0上的asmx (.net 2.0) Web服务发送请求,然后Web服务会向第三方Web服务发送第二个HTTP请求。平均而言,第三方服务需要500毫秒才能响应,但我们被告知只有在有11个并发请求时才会开始排队请求。
为了满足我们的处理SLA,我们需要能够每小时处理79,000条消息或每分钟约1300条消息。如果我们能够让11个并发请求同时进行,并且平均处理时间为500毫秒,那么我们应该能够每秒处理约20条消息。
我们面临的问题是,我们无法接近这些数字。我们的部署解决方案如下。我们有一个服务,每5秒轮询一次数据库以检索100个新消息批次,然后将它们发送到分布器,该分布器负载均衡四个工作窗口服务在两个服务器上运行。我称它们为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,似乎表明如果要对同一Web服务进行多个并发调用,则必须调整IIS 6.0进程模型。
引用文章中的内容: 如果您从每个ASPX页面向单个IP地址进行一次Web服务调用,Microsoft建议使用以下配置设置: 将maxWorkerThreads参数和maxIoThreads参数的值设置为100。 将maxconnection参数的值设置为12*N(其中N是您拥有的CPU数量)。 将minFreeThreads参数的值设置为88*N,将minLocalRequestFreeThreads参数的值设置为76*N。 将minWorkerThreads的值设置为50。请记住,默认情况下,配置文件中没有minWorkerThreads。您必须添加它。
如果有人能够解释发生了什么或解决方案是什么,我将非常感激。
谢谢,
查理

2
请给出投票者,告诉原帖作者需要改正什么才能避免被投票。 - Jonathan M
2
我没有看到任何关于编程的问题。 - bmargulies
@bmargulies - 所以一个关于复杂性能问题的问题不是一个编程问题?你“必须”有代码吗? - Oded
是的,我们已经查看了每个组件,asmx Web服务调用第三方Web服务后执行其工作的平均时间为40毫秒。 - Charlie Barker
在我理解发生了什么之前,我无法编写解决此问题的程序,但如果您有更合适的堆栈站点建议,我非常乐意倾听。 - Charlie Barker
显示剩余7条评论
3个回答

2
一种可能性是:
所有你的.NET Web请求都通过ServicePointManager路由,每个对象默认最多只能有两个并发连接。请参见ServicePointManager.DefaultConnectionLimit
因此,如果你的第三方Web服务平均需要500毫秒响应,单个服务器每秒只能执行四个该服务的请求(即每500毫秒进行两个并发请求)。
将这个乘以两个服务器,你就得到了大约每秒8个消息。
尝试在启动程序时设置ServicePointManager.DefaultConnectionLimit = 4;,看看是否可以提高吞吐量。

我会尝试一下并告诉你。 - Charlie Barker

0

听起来可能有很多原因。

  1. 您是否使用商业可用的NServiceBus标准版?如果没有,您的处理程序将单线程工作。
  2. 您的中间层Web服务是否是异步的?如果第二个服务往返以同步方式进行,则会占用一个线程,无法处理传入的请求。
  3. 您是否配置了足够的工作线程来处理传入的请求? 更新:请参阅此页面http://msdn.microsoft.com/en-us/library/ff647787.aspx#scalenetchapt06_topic9(“表6.1:降低争用的推荐线程设置”)以获取高吞吐量建议。您应该查看的设置是minFreeThreads、maxconnection、maxWorkerThreads和minWorkerThreads。

如果您不能在不进行大规模优化的情况下可靠地实现每秒20条消息的吞吐量,则我会感到紧张。

还有一个可能很愚蠢的问题,为什么您不能直接从消息处理程序调用远程服务?


我们正在使用早于商业版本的2.0版本,该版本没有单线程节流。中间层Web服务不是异步的,所以这可能是问题所在,我可以部署多个此服务实例以查看吞吐量是否增加。如果这是问题所在,您知道将其更改为异步是否会解决问题吗? 关于第3点,这个配置应该在哪里进行? 这不是一个愚蠢的问题,这可能是最好的解决方案,但这意味着要维护两组执行相同任务的代码,中间层服务被其他服务消耗,其中一些是第三方服务。 - Charlie Barker
我想我们也可以修改中间层的Web服务,只需创建一个NServiceBus消息并将其传递给NSB分发器进行处理。然后我们只需要维护一段代码。我认为NServiceBus网关可以以这种方式使用。 - Charlie Barker

0

我建议在系统的每个层面上进行隔离测试。

具体来说,首先排除数据库层面的问题。我会编写一些简单的集成式单元测试,通过使用类似于Parallel.ForEach这样的东西并发运行几百个线程来测试数据库的峰值吞吐量。

然后向上移动一层,并使用类似于存根的东西来“模拟”数据库调用,并验证服务层是否按照预期运行。

这样至少您就能够缩小效率低下的范围并处理它们了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接