Проблема с производительностью IIS при попытке реализовать протокол, подобный XMPP
-
02-07-2019 - |
Вопрос
у нас есть клиент, которому необходимо получать интерактивные сообщения с сервера, от клиентов, которые распределены по всему миру за всеми видами брандмауэров с закрытыми портами всех видов.Единственное, на что мы можем положиться, — это HTTP-порт 80 (и HTTPS 443).
Дизайн в основном смоделирован по образцу XMPP (протокол Jabber) с использованием нашего клиента и IIS.Клиент отправляет запросы GET обработчику .NET;обработчик некоторое время держит запрос открытым в поисках сообщений.Если приходят какие-либо сообщения, они немедленно отправляются клиенту;в противном случае по истечении таймаута соединение закрывается с ответом «нет данных».Клиент немедленно возобновляет общение.
Ну, теоретически.
На самом деле происходит следующее: IIS не может обрабатывать более 100 одновременных запросов — все остальные находятся в очереди, и между «подключением» и IIS, распознающим вызов клиента, может быть задержка в несколько минут.Во-вторых, примерно в половине случаев время ожидания клиента истекает без какого-либо ответа от сервера (время ожидания клиента на пять минут больше, чем время ожидания сервера).
POST всегда работает.Другие данные, передаваемые на тот же веб-сервер, работают.Веб-сервисы на том же сервере работают.Это готовая установка на Windows 2K3 Server.
Есть ли какой-то параметр конфигурации, который нам не хватает, или есть что-то еще, на что мне следует обратить внимание, чтобы решить эту проблему?
Спасибо.
Решение
Я думаю, что вы превышаете ограничения пула потоков ASP.NET, а не IIS.Изучите возможность создания асинхронного обработчика HTTP (IHttpAsyncHandler
), поскольку когда они блокируют/ожидают, они не связывают пул потоков (вместо этого они используют порты завершения).
Обновлять:Недавно наткнулся на это, которое, кажется, совпадает с моими мыслями: КодПроект:Масштабируемая COMET в сочетании с ASP.NET
Другие советы
Если IIS не соответствует вашим требованиям, вам следует выбрать другой веб-сервер, например Апач (с Мод_моно) или ЛайтТПД.
Кстати, вы можете туннелировать XMPP через HTTP, используя XMPP поверх БОШ.Нет необходимости изобретать собственный протокол.
Изначально Windows нуждается в некоторой доработке.Мне пришлось реализовать сервер Comet в asp.net, и я столкнулся с некоторыми глупыми настройками по умолчанию.Прочитав эти ссылки:
- Ошибки IIS 7.0 503 с универсальным обработчиком (.ashx), реализующим IHttpAsyncHandler
- http://blogs.technet.com/b/winserver Performance/archive/2008/07/25/tuning-windows-server-2008-for-php.aspx
- http://smallvoid.com/article/winnt-tcpip-max-limit.html
- http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/rprf_plugin.html
- http://support.microsoft.com/kb/820129
- http://msdn.microsoft.com/en-us/library/ee37705(BTS.10).aspx
- http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx
Я внес следующие изменения в наш сервер Windows 2k8.
- reg add HKLM\System\CurrentControlSet\Services\HTTP\Parameters /v MaxConnections /t REG_DWORD /d 1000000 /f
- reg add HKLM\System\CurrentControlSet\Services cpIp\Parameters /v TcpTimedWaitDelay /t REG_DWORD /d 30 /f
- reg add HKLM\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0 /v MaxConcurrentThreadsPerCPU /t REG_DWORD /d 0 /f
- reg add HKLM\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0 /v MaxConcurrentRequestsPerCPU /t REG_DWORD /d 30000 /f
- appcmd.exe устанавливает пул приложений «[имя пула приложений]» /queueLength:65535
- appcmd.exe устанавливает конфигурацию /section:serverRuntime /appConcurrentRequestLimit:100000
- reg add HKLM\System\CurrentControlSet\Services cpIp\Parameters /v MaxUserPort /t REG_DWORD /d 65534 /f
- reg add HKLM\System\CurrentControlSet\Services cpIp\Parameters /v MaxFreeTcbs /t REG_DWORD /d 2000 /f
- reg добавить hklm System currentControlSet services tcpip parameters /v maxhashtablize /t reg_dword /d 2048 /f reg add hklm system currentcontrolset services inetinfo parameters /v maxpoolthreads /t Reg_dword /d 80 /f
- appcmd set config /section:processModel /requestQueueLimit:100000 /commit:MACHINE
Я не знаю, были ли все изменения обязательны или оптимальны, но после некоторого быстрого тестирования на тестовом сервере мы достигли более 30 тысяч выполняемых подключений и 5 тысяч запросов в секунду.Я не мог идти дальше, потому что у меня закончились клиентские машины для запуска тестов.
XMPP никогда не предназначался для высокопроизводительных приложений.Сообщения должны пройти через весь стек на уровень приложения, и здесь выполняется большой анализ XML.Рассматривали ли вы возможность использования какого-либо другого стандарта помимо XMPP?