Я сталкиваюсь с некоторыми проблемами производительности, используя универсальный обработчик, который реализует IHttpAsyncHandler. В самом простом случае обработчик получает запрос GET и через 20 секунд завершает ответ, написав в ответ '‹ timeout / >'.
При забивании .ashx с 10000-20000 одновременных запросов он вылетает с 503 сервер недоступен ровно после 5000 запросов. При переключении в синхронный режим и немедленном завершении запроса проблема исчезает.
Я возился с рядом настроек, но единственное, чего мне удалось добиться, это снизить порог запроса, при котором возникает эта ошибка.
Вот краткое изложение настроек, с которыми я играл:
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));
}
}
}
}