ASP.NET MVC2 в веб-ферме — медленная загрузка страницы при высоком трафике

#linq-to-sql #asp.net-mvc-2 #iis-7.5 #web-farm #nlb

#linq-to-sql #asp.net-mvc-2 #iis-7.5 #веб-ферма #nlb

Вопрос:

У нас есть веб-приложение, написанное на MVC2 Linq2SQL MS SQL SERVER 2008, размещенное на веб-ферме. Почти как stackoverflow.com

У нас есть 4 x IIS7 1 SQL SERVER 2008, сбалансированный по нагрузке с MS NLB

Статическое содержимое кэшируется внешним поставщиком кэша — Akamai, что сокращает 86% запросов.

Каждый веб-сервер имеет 32 ГБ оперативной памяти и 4 четырехъядерных процессора, поэтому во внешнем интерфейсе 64 ядра.

Мы сохраняем состояние сеанса в таблицах.

Он отлично работает со средним трафиком (загрузка страницы = 0,2 с), но компания делает телевизионную рекламу, и во время этих объявлений трафик достигает 20 000 пользователей в течение 20-30 секунд.

В этот момент страница замедляется до 8-10 секунд. Однако использование ЦП и памяти даже не достигает 40% ни на одном компьютере.

Пропускная способность центра обработки данных не достигает половины своих пределов.

Медленные страницы генерируют данные из простых выборок максимум из 10 записей только из 1-2 таблиц.

Очевидно, что где-то есть узкое место, и я пытаюсь выяснить, где именно.

У кого-нибудь есть какие-либо советы для меня, где искать проблему?

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

1. Я думаю, что слишком много SELECT в этих таблицах вызывает эту проблему. Есть ли у вас правильные индексы и т. Д. В этих таблицах на основе вашего предложения WHERE?

2. Я согласен с Анкуром. Похоже, что в базе данных выполняется чрезмерное количество запросов. Проверьте свои индексы, использование ToList(), Any() и т.д. Это все функции, которые выполняют вызовы к базе данных. Вы также можете использовать такой инструмент, как dotTrace, для профилирования вашего приложения и посмотреть, что произойдет.

3. Я кластеризовал индексы по всем столбцам PK и просмотрел планы выполнения. Я не думаю, что отсутствие дополнительных индексов может вызвать это узкое место. Это, безусловно, помогает, но я бы получил небольшой процент. Я ищу большой выигрыш. Поэтому я также думал о дисковом вводе-выводе блока SQL server и разделении базы данных на несколько разных файлов, размещенных на нескольких разных дисках, чтобы улучшить параллелизм дискового ввода-вывода. Как сказано здесь: tinyurl.com/6xfxuso

Ответ №1:

Я обнаружил проблему некоторое время назад, но у меня не было времени опубликовать ее здесь. Я перепробовал почти все, что мог придумать: индексы, оптимизацию sql, мониторинг дискового ввода-вывода, пересмотр кода. Ничто из вышеперечисленного не решило мою проблему. Я запускаю веб-стресс-тест с 2 рабочих станций в нашей локальной сети, и я могу заморозить всю страницу за считанные секунды! Во время выполнения тестов я заметил что-то странное. Я создал отдельный контроллер для тестирования и поставил 2 метода. Оба делают одно и то же: запрашивают одни и те же данные на нашем сервере базы данных.

Действие А)

 public ActionResult Index(){
var model = new SomeModel();
// Get data
....
return View(model);
}
  

Действие B)

 public ActionResult Index() {
 var model = new SomeModel();
// Get data
....
return View("Index",model);
}
  

Разница в загрузке страницы:

A) ~ 297 мс

Б) ~ 39,47 с

Это происходит только при высоком уровне параллелизма, в противном случае все в порядке. Похоже, что поиск представления по умолчанию в библиотеке MVC2 вызывает проблему, поскольку после его указания все работает отлично.

Я описал это в своем блоге:

http://arturito.net/2011/10/24/asp-net-mvc2-in-the-web-farm-slow-page-load-with-high-traffic-where-is-the-bottleneck/

Я опубликовал это в журнале отслеживания проблем asp.net на codeplex, но никто еще не прокомментировал / не ответил на него.

http://aspnet.codeplex.com/workitem/9396

Ответ №2:

Для некоторых меньших преимуществ в производительности вы можете попробовать некоторые из настроек, о которых упоминает Рико Мариани в http://blogs.msdn.com/b/ricom/archive/2007/06/22/dlinq-linq-to-sql-performance-part-1.aspx . В частности, попробуйте использовать CompiledQuery и отключить отслеживание изменений для объектов только для отображения.