У меня неприятная проблема, которую я не могу объяснить. Проще говоря, использование ЦП необъяснимо велико на веб-серверах в моей веб-ферме.
У меня большое количество пользователей, использующих два интерфейсных веб-сервера. 99% загрузок страницы являются Ajax-запросами и обслуживают простой сериализованный JSON-объект, который веб-серверы получают из бэкэнда с помощью WCF. В типичном случае (опять же, вероятно, 99% запросов) все, что делает страница ASPX, - это вызов WCF, чтобы получить эти данные, сериализовать их в строку JSON и вернуть их.
Объект довольно маленький - гид, пара коротких строк, несколько целых.
Нетипичным случаем является начальная загрузка страницы, которая делает то же самое (запрос WCF), но вводит ответ в разные части страницы, используя asp: literals.
Все три машины (2 веб-сервера, один сервер) имеют одинаковые характеристики. Я ожидаю, что бэкэнд выполнит большую часть работы в этой ситуации, так как он управляет всеми данными, выполняет поиск и т. Д. НО: нагрузка на бэкэнд на намного меньше, чем нагрузка на передние концы. Бэкэнд - это хорошая загрузка процессора на уровне 10-20%. Внешние интерфейсы работают в среднем на 30%, но они по всей карте, иногда ударяя по 100% в течение 10 секунд и тратя 600 мс на обслуживание этих очень простых страниц.
Когда я запускаю внешний интерфейс в профилировщике (ANTS), он помечает связь WCF как занимающую 80% времени ЦП. Вот и весь вызов созданного .NET WCF-прокси.
Настройка WCF: сервис полностью параллелен. У меня есть экземпляр установлен на «один» и параллелизма на «несколько». Я открыл maxConnections и listenBacklog для службы до 256. В условиях сильной нагрузки (500 запросов / с) я вижу около 75 соединений, открытых как между интерфейсными серверами, так и со службой, поэтому он не попадает в эту стену. Я установил охрану на «нет». Использование полосы пропускания составляет около 1/20 от потенциального (4 Мбит / с в сети 100 Мбит / с).
На клиенте (веб-серверах) я создаю статическую ChannelFactory для службы. Код для вызова службы выглядит так:
service = MyChannelFactory.CreateChannel();
try {
service.Call();
service.Close();
} catch {
service.Abort();
}
(упрощенно, но вы получите базовую картину)
Чего я не понимаю, так это откуда взялась вся эта нагрузка на переднюю часть. Что странного в этом то, что он никогда не находится в диапазоне 30% -90%. Это либо в режиме паники (100%), либо в порядке (30% или меньше). Однако, учитывая нагрузку на серверную часть, я ожидаю, что обе эти машины будут составлять 10% или меньше. Использование памяти, ручки и т. Д., Все кажется разумным.
Чтобы добавить еще одну складку: когда я регистрирую, сколько времени требуется для обслуживания этих вызовов на бэкэнде, я получаю время постоянно менее 15 мс (может быть, один или два всплеска до 30 мс каждую минуту). На входной стороне эти вызовы могут занять до 1 секунды, чтобы вернуться. Я думаю, это может быть из-за проблем с процессором, но мне кажется, что это не так.
Итак ... у кого-нибудь есть идеи о том, где искать подобные вещи? Мне не хватает вещей для исследования.
Уточнение : Служба WCF размещена в службе Windows и использует привязку netTcp. Кроме того, у меня maxConnections на клиенте установлен на 128, FWIW.