пятница, 10 июня 2016 г.

Немасштабируемый вэб сервер IIS - откуда он берется ?

Плохая архитектура


Представим себе что мы написали ASP.NET или WCF приложение без использования асинхронных операций - что произойдет ?

При попытке коннекта от клиента IIS создаст в ThreadPool новый поток, который создаст запрос к базе данных и ЗАБЛОКИРУЕТСЯ ожидая ответа ! В случае с высокой загрузкой сервера, когда блокировки будут возникать быстрее чем база данных отдавать ответы разблокируя поток - число заблокированных потоков будет расти.


Но что самое главное - у этого роста есть четкий предел: -лишь  определенное количество потоков поток ThreadPool сможет создать,  и наступит момент когда система выдаст OutOfMemory Exception ! И данное исключение не может быть обработано - так как исключение возникает в самом ThreadPool и наш код в этот момент находиться в стеке.

То есть что произойдет - процесс сервера будет уничтожен (TerminateProcess) вместе со всеми потоками, но как только первый же клиент создаст запрос - процесс создастся вновь автоматически, и все опять пойдет по кругу !

Возникает "магия" - вдруг ни с того ни с сего клиенты не получают ответов (периодически), но потом все работает как обычно ...


Но на этом трудности сервера не заканчиваются - из-за большого количества создаваемых потоков повышается доля времени которая тратиться на обслуживание этих потоков ( переключение контекста - Context Switching ).Как только вернется ответ от базы ThreadPool будет уничтожать поток.  То есть основное процессорное время тратиться на создание,блокирование,переключение контекста, уничтожение потоков !

Как исправить

Если же мы написали ASP.NET или WCF приложение с использованием асинхронных операций то произойдет следующее. В случае запроса от клиента IIS создаст в ThreadPool новый поток, который сразу же вернет управление . И с высокой степенью вероятности до того как возникнет запрос от другого клиента.


Получается что лишь один поток обслуживает все приходящие запросы, и на случай высокой загрузки у нас еще есть сотни потоков ( а возможно и тысячи, десятки тысяч - в зависимости от железа сервера) до возникновения исключения !

Что нам предлагает фреймворк ASP.NET для этого:


Так что же делать ? На примере одного сервиса я покажу простейший путь:


Комментариев нет :

Отправить комментарий