Комментарии 6
Имхо, приведенная стратегия — это не оптимизация производительности, а бездумное перераспределение ресурсов. Если на сервере комплексная система или несколько систем, то дав больше возможностей отдельно взятому пулу другие можно поставить колом))
> Если же у вас начинаются “зависания” при обработке запросов к различным сервисам — не следует сразу винить во всем железо! Лучше внести изменения в базовую конфигурацию ASP.NET.
Если начинаются «зависания», то начать, мне кажется, стоит с определения источника проблемы. Первый шаг — тот же IIS Failed Request Tracing, который разжевывает все этапы прохождения запросов и соответствующие тайминги. Активно применяется и для исследования проблем производительности.
> Если же у вас начинаются “зависания” при обработке запросов к различным сервисам — не следует сразу винить во всем железо! Лучше внести изменения в базовую конфигурацию ASP.NET.
Если начинаются «зависания», то начать, мне кажется, стоит с определения источника проблемы. Первый шаг — тот же IIS Failed Request Tracing, который разжевывает все этапы прохождения запросов и соответствующие тайминги. Активно применяется и для исследования проблем производительности.
>Имхо, приведенная стратегия — это не оптимизация производительности, а бездумное перераспределение ресурсов.
Не согласен, очень часто бутылочным горлышком является именно maxConnections.
Здесь описано не бездумное перераспределение ресурсов, а тюнинг. Разработчики приложений сами должны оценить — подойдут ли им значения по умолчанию, которые рекомендует MS или использовать свои.
>Если начинаются «зависания», то начать, мне кажется, стоит с определения источника проблемы. Первый шаг — тот же IIS Failed Request Tracing, который разжевывает все этапы прохождения запросов и соответствующие тайминги. Активно применяется и для исследования проблем производительности.
В первую очередь стоит все таки обратить внимание на счетчики производительности, а не IIS Freb логи. Они вам например не покажут, что cpu загружен на 100%.
Не согласен, очень часто бутылочным горлышком является именно maxConnections.
Здесь описано не бездумное перераспределение ресурсов, а тюнинг. Разработчики приложений сами должны оценить — подойдут ли им значения по умолчанию, которые рекомендует MS или использовать свои.
>Если начинаются «зависания», то начать, мне кажется, стоит с определения источника проблемы. Первый шаг — тот же IIS Failed Request Tracing, который разжевывает все этапы прохождения запросов и соответствующие тайминги. Активно применяется и для исследования проблем производительности.
В первую очередь стоит все таки обратить внимание на счетчики производительности, а не IIS Freb логи. Они вам например не покажут, что cpu загружен на 100%.
Не согласен, очень часто бутылочным горлышком является именно maxConnections.
На основании чего сделаны такие выводы? Я бы на Вашем месте, прошелся по ссылкам, которые привел ТС. Хоть им больше 10 лет и касаются в основном IIS 6 + .NET 1.0, но общие концепции оптимизации там приведены хорошо и настройка пула предваряется немалым количеством предварительных мероприятий.
Здесь описано не бездумное перераспределение ресурсов, а тюнинг.
Я апеллировал к заголовку статьи, где написано оптимизация. Я думаю, разницу между оптимизацией и тюнингом не надо объяснять. Следующий вопрос — тюнинг для каких целей? Максимизации количества пользователей? Минимизации TTFB/TTLB? Минимизации потребляемых ресурсов? Если вы занимались настройкой высоконагруженного IIS, то должны знать, что поднятые воркеры, раздутая очередь не даются бесплатно. RPS может вырасти, но какой ценой.
В первую очередь стоит все таки обратить внимание на счетчики производительности, а не IIS Freb логи. Они вам например не покажут, что cpu загружен на 100%.
Лог отвечает на вопрос, что именно нагружает, нагружает ли вообще, в IIS ли дело. После этого я могу поставить нужный счетчик на нужный объект или понять, что счетчики мне вообще не нужны, что надо профилировать приложение, собирать wait statistics с sql-сервера и т.п. Счетчик на загрузку CPU… ну узнали Вы, что он загружен. Что дальше? Я знал о том, что некоторый компонент системы (не обязательно CPU) нагружен еще до того, как начал оптимизацию.
>На основании чего сделаны такие выводы? Я бы на Вашем месте, прошелся по ссылкам, которые привел ТС. Хоть им больше 10 лет и касаются в основном IIS 6 + .NET 1.0, но общие концепции оптимизации там приведены хорошо и настройка пула предваряется немалым количеством предварительных мероприятий.
К сожалению я не смотрел приведенные ссылки. Но могу например сказать, что до 4го фреймворка дефолтовое значение параметра maxConnections было равно 2. Сейчас все приведенные выше параметра по дефолту расчитываются исходя из количество ядер процессора. Таким образом статья актуальна)
Почему я привел пример с maxConnections? Просто я обычно работал с ASP.NET приложениями, которые выступали клиентам к множеству внешних удаленных сервисов.
>Следующий вопрос — тюнинг для каких целей?
Так почитайте раздел «предыстория». Если в кратце, то как я понимаю, автор статьи столкнулся с проблемой, когда при превышении какой то определенного числа пользователей, сервер становился неработоспособным. При этом загрузка CPU, памяти и других аппаратных ресурсов оставалась в норме.
Профлирование серверного когда не выявило проблем.
А вот например снятие Full User Dump с процесса w3wp показало, что нет свободных хенделеров для обработки всей очереди http реквестов, или например в дампе наблюдается большая очередь коннектов на внешний бекенд сервис. Это конечно я утрирую. Т.к. автор не указал точной причины, почему же все таки было принято решение менять настройки апп пула и asp.net приложения.
>cчетчик на загрузку CPU… ну узнали Вы, что он загружен. Что дальше? Я знал о том, что некоторый компонент системы (не обязательно CPU) нагружен еще до того, как начал оптимизацию.
Да любой профайлер Вам в помощь) Например dotTracePerfomance, Подключаетесь к процесс w3wp, проводите нагрузочное тестирование, и определяете, что грузит процессор. Интересует именно %UserTime, всякие сериализации, десериализации, вычисления и тп.
К сожалению я не смотрел приведенные ссылки. Но могу например сказать, что до 4го фреймворка дефолтовое значение параметра maxConnections было равно 2. Сейчас все приведенные выше параметра по дефолту расчитываются исходя из количество ядер процессора. Таким образом статья актуальна)
Почему я привел пример с maxConnections? Просто я обычно работал с ASP.NET приложениями, которые выступали клиентам к множеству внешних удаленных сервисов.
>Следующий вопрос — тюнинг для каких целей?
Так почитайте раздел «предыстория». Если в кратце, то как я понимаю, автор статьи столкнулся с проблемой, когда при превышении какой то определенного числа пользователей, сервер становился неработоспособным. При этом загрузка CPU, памяти и других аппаратных ресурсов оставалась в норме.
Профлирование серверного когда не выявило проблем.
А вот например снятие Full User Dump с процесса w3wp показало, что нет свободных хенделеров для обработки всей очереди http реквестов, или например в дампе наблюдается большая очередь коннектов на внешний бекенд сервис. Это конечно я утрирую. Т.к. автор не указал точной причины, почему же все таки было принято решение менять настройки апп пула и asp.net приложения.
>cчетчик на загрузку CPU… ну узнали Вы, что он загружен. Что дальше? Я знал о том, что некоторый компонент системы (не обязательно CPU) нагружен еще до того, как начал оптимизацию.
Да любой профайлер Вам в помощь) Например dotTracePerfomance, Подключаетесь к процесс w3wp, проводите нагрузочное тестирование, и определяете, что грузит процессор. Интересует именно %UserTime, всякие сериализации, десериализации, вычисления и тп.
3. Параметр minWorkerThreads — указывает минимальное количество рабочих потоков для каждого процессора, которые могут быть предоставлены немедленно для обслуживания удаленного запроса. Значение по умолчанию — 1.
4. Параметр minIoThreads — указывает минимальное количество потоков ввода/вывода для каждого процессора, которые могут быть предоставлены немедленно для обработки обратного вызова. Значение по умолчанию — 1.
В данном случае следует предостеречь от слишком буквального понимания слова «немедленно». Добавление новой пачки из min[тип_пула]Threads тредов в пул происходит раз в 500 миллисекунд (при дефолтных значениях это 2 потока в секунду).
Поэтому при слишком низких значениях этих параметров холодный старт сервиса (например после ресайклинга апп пула) его прогрев и выход на расчетную производительность может занят значительное время. Подробности можно почитать по ссылке WCF scales up slowly with bursts of work
В случае хостинга WCF сервиса в IIS это приводит к интересным спецэффектам.
P.S. Попытка обнаружить это с помощью профайлера не дает никаких результатов. А вот мониторинг системных счетчиков рисует очень наглядную картину.
dreik, вы указали важный момент, на который стоит обратить внимание и ссылка очень хорошая :)
Однако всё таки в данном случае слово «немедленно» нужно понимать буквально.
Поясню: параметры minIoThreads/minWorkerThreads необходимо задавать для обеспечения работоспособности приложения в случае, когда происходит «взрыв нагрузки» (Burst Load), т.е. количество пользователей возрастает по экспоненте. Если до часа «Х» нагрузка на сайте была невысокая, то в пуле имеется небольшое количество потоков. Таким образом, CLR ThreadPool используя собственный алгоритм распределения потоков может не иметь достаточно времени, чтобы достичь оптимального уровня потоков, т.к. на создание пары новых потоков в пуле уходит около 1сек. Установка параметров minIoThreads/minWorkerThreads позволяет пулу справиться с возросшей нагрузкой в штатном режиме, т.к. минимальное заданное количество «Worker» и «IO» потоков будут созданы и использованы пулом «немедленно».
Причём, начиная с .NET Framework 4, пул потоков создает и уничтожает потоки в целях оптимизации производительности, поэтому количество текущих потоков в пуле может быть ниже минимального заданного значения minIoThreads/minWorkerThreads. Однако по требованию необходимые потоки для пула могут быть созданы очень быстро до минимальных значений, а при снижении нагрузки они опять удаляются. На MSDN в разделе ThreadPool Class можно починать подробнее про это.
p.s. В реальной жизни наглядный пример такой ситуации — это получение зарплаты/премии сотрудниками какой-нибудь крупной компании в определённое время, когда все спешат на сайт побыстрее увидеть, сколько же им начислили деньжат ))
Однако всё таки в данном случае слово «немедленно» нужно понимать буквально.
Поясню: параметры minIoThreads/minWorkerThreads необходимо задавать для обеспечения работоспособности приложения в случае, когда происходит «взрыв нагрузки» (Burst Load), т.е. количество пользователей возрастает по экспоненте. Если до часа «Х» нагрузка на сайте была невысокая, то в пуле имеется небольшое количество потоков. Таким образом, CLR ThreadPool используя собственный алгоритм распределения потоков может не иметь достаточно времени, чтобы достичь оптимального уровня потоков, т.к. на создание пары новых потоков в пуле уходит около 1сек. Установка параметров minIoThreads/minWorkerThreads позволяет пулу справиться с возросшей нагрузкой в штатном режиме, т.к. минимальное заданное количество «Worker» и «IO» потоков будут созданы и использованы пулом «немедленно».
Причём, начиная с .NET Framework 4, пул потоков создает и уничтожает потоки в целях оптимизации производительности, поэтому количество текущих потоков в пуле может быть ниже минимального заданного значения minIoThreads/minWorkerThreads. Однако по требованию необходимые потоки для пула могут быть созданы очень быстро до минимальных значений, а при снижении нагрузки они опять удаляются. На MSDN в разделе ThreadPool Class можно починать подробнее про это.
p.s. В реальной жизни наглядный пример такой ситуации — это получение зарплаты/премии сотрудниками какой-нибудь крупной компании в определённое время, когда все спешат на сайт побыстрее увидеть, сколько же им начислили деньжат ))
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Оптимизация ASP.NET — практические советы по работе с IIS