我在使用实现了IHttpAsyncHandler接口的通用处理程序时遇到了性能问题。在最简单的情况下,处理程序收到GET请求,并在20秒后向响应中写入“<timeout/>”,然后结束响应。
当同时向.ashx发送10000-20000个请求时,它会在恰好5000个请求后出现503服务器不可用错误。当切换到同步模式并立即结束请求时,问题消失了。
我尝试过许多设置,但我所做的唯一事情就是降低发生此错误的请求阈值。
以下是我尝试过的设置:
machine.config:
虽然我不能确定,但似乎这些设置只适用于同步请求的情况下才能正常工作,但在异步请求时,我似乎无法超过5000个请求,否则服务器就会告诉我离开。如果我把它们设置得更低(记不清上面具体是哪个设置了,但我已经尝试过所有的设置),那么503计数也会相应增加,但在严重负载下始终无法阻止它发生超过5000次。
看起来有很多分散在许多地方的设置可能会影响到这个问题,但5000似乎是比较固定的。我在这里看到appRequestQueueLimit不能超过5000,但找不到进一步的信息,想知道这是否是错误信息。
在IIS中是否有任何“洪水控制”设置可能限制单个主机的请求数量不超过5000?如何让IIS处理超过5000个并发异步请求?
编辑2:是否有任何计数器或其他指标可以判断哪个限制被超过了,如何进一步调查此问题?
编辑:这是负载生成器代码:
当同时向.ashx发送10000-20000个请求时,它会在恰好5000个请求后出现503服务器不可用错误。当切换到同步模式并立即结束请求时,问题消失了。
我尝试过许多设置,但我所做的唯一事情就是降低发生此错误的请求阈值。
以下是我尝试过的设置:
machine.config:
<configuration>
...
<system.web>
...
<processModel enable="true" requestQueueLimit="10000"/>
...
web.config:
<configuration>
...
<system.web>
...
<httpRuntime enable="true" appRequestQueueLimit="10000"/>
...
IIS 管理器 > 应用程序池 > 高级设置
Queue Length : 65535
虽然我不能确定,但似乎这些设置只适用于同步请求的情况下才能正常工作,但在异步请求时,我似乎无法超过5000个请求,否则服务器就会告诉我离开。如果我把它们设置得更低(记不清上面具体是哪个设置了,但我已经尝试过所有的设置),那么503计数也会相应增加,但在严重负载下始终无法阻止它发生超过5000次。
看起来有很多分散在许多地方的设置可能会影响到这个问题,但5000似乎是比较固定的。我在这里看到appRequestQueueLimit不能超过5000,但找不到进一步的信息,想知道这是否是错误信息。
在IIS中是否有任何“洪水控制”设置可能限制单个主机的请求数量不超过5000?如何让IIS处理超过5000个并发异步请求?
编辑2:是否有任何计数器或其他指标可以判断哪个限制被超过了,如何进一步调查此问题?
编辑:这是负载生成器代码:
using System;
using System.Net;
using System.Threading;
namespace HammerTime
{
class Program
{
private static int counter = 0;
static void Main(string[] args)
{
var limit = 5000;
ServicePointManager.DefaultConnectionLimit=limit;
for (int i = 0; i < limit;++i )
{
StartWebRequest(i.ToString());
}
Console.ReadLine();
}
private static void StartWebRequest(string channelId)
{
string uri = "http://spender2008/test/Test.ashx?channel="+channelId;
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(uri);
request.BeginGetResponse(responseHandler, request);
}
private static void responseHandler(IAsyncResult ar)
{
try
{
HttpWebRequest state = (HttpWebRequest)ar.AsyncState;
HttpWebResponse response = (HttpWebResponse)state.EndGetResponse(ar);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
Console.WriteLine(Interlocked.Increment(ref counter));
}
}
}
}