我在使用实现 IHttpAsyncHandler 的通用处理程序时遇到了一些性能问题。在最简单的情况下,处理程序接收到一个 GET 请求,并在 20 秒后将“< timeout />”写入响应后结束响应。
当用 10000-20000 个同时请求敲击 .ashx 时,它会在恰好 5000 个请求后失败,503 服务器不可用。当切换到同步模式并立即结束请求时,问题就消失了。
我已经修改了许多设置,但我唯一设法实现的是降低发生此错误的请求阈值。
这是我玩弄过的设置的简要说明:
机器配置:
<configuration>
...
<system.web>
...
<processModel enable="true" requestQueueLimit="10000"/>
...
网络配置:
<configuration>
...
<system.web>
...
<httpRuntime enable="true" appRequestQueueLimit="10000"/>
...
IIS 管理器 > 应用程序池 > 高级设置
Queue Length : 65535
虽然我不能确定,如果请求是同步的,这些设置似乎工作得很好,但是当异步时,在服务器开始告诉我离开之前,我似乎无法超过 5000 个请求。如果我把事情设置得更低(不记得上面到底是哪个设置,但我都试过了),那么 503 计数会相应增加,但在严重负载下我永远无法阻止它超过 5000 .
似乎有许多设置分散在可能会影响这一点的无数地方,但 5000 似乎相当固定。我在这里看到 appRequestQueueLimit 不能超过 5000,但找不到有关此的更多信息,并且想知道这是否是错误信息。
IIS 中是否有任何类型的“洪水控制”设置可能将单个主机限制为不超过 5000 个请求?如何让 IIS 处理超过 5000 个并发异步请求?
Edit2:是否有任何可能超出限制的计数器或其他指标,我将如何进一步调查?
编辑:这是负载生成器代码:
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));
}
}
}
}