Ответ 1
Я сделал что-то подобное в https://github.com/JamesDunne/Aardwolf и провел несколько обширных тестов.
См. код https://github.com/JamesDunne/aardwolf/blob/master/Aardwolf/HttpAsyncHost.cs#L107 для реализации цикла основного события.
Я считаю, что использование Semaphore
для управления количеством параллельных запросов GetContextAsync
является самым лучшим подходом. По существу, основной цикл продолжает работать до тех пор, пока семафор не блокирует поток из-за достижения счетчика. Затем будет активировано N одновременных активных подключений. Каждый раз, когда соединение принимается, семафор освобождается, и новый запрос может занять его место.
Начальные и максимальные значения семафора требуют некоторой тонкой настройки в зависимости от нагрузки, которую вы ожидаете получить. Это тонкий баланс между количеством параллельных подключений, которые вы ожидаете, против среднего времени отклика, которое пожелают ваши клиенты. Более высокие значения означают, что большее количество соединений может поддерживаться еще при значительно более медленном среднем времени отклика; меньшее количество соединений будет отклонено. Более низкие значения означают, что меньше соединений можно поддерживать еще со значительно более быстрым средним временем отклика; больше соединений будет отклонено.
Я нашел, экспериментально (на моем оборудовании), что значения вокруг 128
позволяют серверу обрабатывать большое количество одновременных подключений (до 1,024) при приемлемом времени отклика. Протестируйте с помощью собственного оборудования и соответствующим образом настройте свои параметры.
Я также обнаружил, что один экземпляр WCAT не любит обрабатывать более 1024 подключений. Поэтому, если вы серьезно относитесь к нагрузочному тестированию, используйте несколько клиентских машин с WCAT против вашего сервера и не забудьте протестировать более быструю сеть, например. 10 GbE и что ограничения вашей ОС не замедляют вас. Обязательно проверяйте на SKU сервера Windows, потому что по умолчанию для SKU для ПК ограничено.
Резюме: Как вы пишете цикл принятия соединения, критически важно для масштабируемости вашего сервера.