是什么导致了这种情况下的瓶颈?
我正在寻求一些帮助来解决我们遇到的生产问题。
我们有一个 NServiceBus 处理程序,当它处理消息时,它会向运行在 IIS 6.0 上的 asmx (.net 2.0) Web 服务发送请求,然后该 Web 服务将第二个 http 请求发送到第 3 方 Web 服务,平均为第 3 方服务需要 500 毫秒才能响应,但我们被告知只有当 11 个并发请求正在进行时才会开始排队请求。
为了满足我们的处理 SLA,我们需要能够每小时处理 79,000 条消息或每分钟大约 1300 条消息。并行处理 11 个请求,平均需要 500 毫秒,如果我们能够触发 11 个并发请求,那么这应该是可以实现的,每秒我们应该能够处理大约 20 条消息。
我们面临的问题是我们无法接近这些数字。我们部署的解决方案如下。我们有一项服务可以每隔一段时间轮询一次数据库 5 秒内检索一批 100 条新消息,它将它们发送到分发器,该分发器在两台服务器上运行的四个工作窗口服务之间进行负载平衡。我将它们称为 NsbServerA & NSb服务器B。每个工作服务配置有 2 个线程,因此总共有 8 个线程。我们有两台运行 asmx Web 服务的服务器,我将其称为 asmx1 和 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 不在配置文件中。你必须添加它。”
如果有人能够阐明正在发生的事情或解决方案是什么,我将非常感激。
谢谢,
查理
I'm looking for some help with a production issue we have encountered.
We have an NServiceBus Handler that when it processes a message sends a request to an asmx (.net 2.0) webservice running on IIS 6.0, the web service then sends a second http request to a 3rd Party web service, on average the 3rd party service takes 500ms to respond but we have been told will only start queing requests when 11 simultaneous requests are in progress.
To meet our processing SLA's we need to be able to process 79,000 messages an hour or ~ 1300 messages a minute. With 11 requests being processed in parallel and taking an average of 500 ms this should be achievable if we can get eleven concurrent requests firing, every second we should be able to process about 20 messages.
The problem we have is that we cannot get anywhere near these figures. Our deployed solution is as follows. We have a service that polls a database every
5 seconds to retrieve a batch of 100 new messages, it sends them to a distributor which load balances accross four worker windows services running on two servers. I'll call them NsbServerA & NSbServerB. Each worker service is configured with 2 threads so we have 8 threads in total. We have two servers runing the asmx web services I'll call the asmx1 & asmx2, ServerA sends requests to asmx1 and ServerB sends requests to asmx2.
The current throughput is 30,000 messages per hour, ~500 per min, ~8 per second so somewhere we have a bottle neck the question is where?
I have seen this article http://support.microsoft.com/default.aspx?scid=kb;en-us;821268 which seems to indicate that you have to tune the IIS 6.0 process model if you want to make more than a few of concurrent calls to the same webservice.
Quote from the article:
"If you are making one Web service call to a single IP address from each ASPX page, Microsoft recommends that you use the following configuration settings:
Set the values of the maxWorkerThreads parameter and the maxIoThreads parameter to 100.
Set the value of the maxconnection parameter to 12*N (where N is the number of CPUs that you have).
Set the values of the minFreeThreads parameter to 88*N and the minLocalRequestFreeThreads parameter to76*N.
Set the value of minWorkerThreads to 50. Remember, minWorkerThreads is not in the configuration file by default. You must add it."
If anyone can shed some light on what is happening or what the solution is I would be really grateful.
Thanks,
Charlie
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一种可能的可能性是:
所有 .NET Web 请求都通过 ServicePointManager 进行路由,默认情况下每个对象有两个并发连接。请参阅 ServicePointManager.DefaultConnectionLimit。
因此,如果您的第 3 方 Web 服务平均需要 500 毫秒进行响应,则单个服务器每秒只能对该服务执行四个请求。 (即每 500 毫秒有两个并发请求)。
将其乘以两台服务器,您每秒会收到约 8 条消息。
尝试在启动程序时设置
ServicePointManager.DefaultConnectionLimit = 4;
,并查看是否会增加吞吐量。One likely possibility:
The ServicePointManager, through which all your .NET Web requests are routed, has a default of two concurrent connections per object. See ServicePointManager.DefaultConnectionLimit.
So if your 3rd party Web service takes an average of 500 ms to respond, a single server can only do four requests to that service every second. (i.e. two concurrent requests every 500 ms).
Multiply that by two servers and you get your ~8 messages per second.
Try setting
ServicePointManager.DefaultConnectionLimit = 4;
when you start your program, and see if that increases your throughput.我建议单独测试系统的每一层。
具体来说,首先将数据库层视为一个问题。我将一些简单的集成式单元测试放在一起,以测试数据库的峰值吞吐量,理想情况下通过使用诸如 Parallel.ForEach 之类的东西来同时运行数百个线程。
然后向上移动一层并使用存根之类的东西来“模拟”数据库调用并验证服务层是否按其应有的方式运行。
那么至少您将能够缩小效率低下的范围并解决它们。
I would suggest testing each layer of the system in isolation.
Specifically, first discount the database tier as an issue. I'd put together some simple integration-style unit tests that exercise the peak throughput of the database, ideally by using something like
Parallel.ForEach
to run a few hundred threads concurrently.Then move up a layer and use something like a stub to "mock out" the database calls and verify that the service tier is behaving as it should.
Then at least you'll be able to narrow down the inefficiencies and deal with them.
听起来可能有很多事情。
如果您在没有大规模优化的情况下无法可靠地实现这一目标,那么我会担心承诺每秒 20 条消息的吞吐量 SLA。
也可能是一个愚蠢的问题,但为什么不能直接从消息处理程序调用远程服务?
Sounds like it could be many things.
I would be nervous committing to a throughput SLA of 20 messages per second if you cannot reliably achieve this without massive optimization.
Also probably a stupid question but why can't you call the remote service from your message handler directly?