Назад | Перейти на главную страницу

Уменьшение очереди запросов Apache

В New Relic одна из метрик, отображаемых как часть времени ответа приложения, - «Очередь запросов»:

Чтобы собрать время ожидания запросов в очереди, вам необходимо пометить HTTP-запрос меткой времени при запуске очереди. [1]

Это делается путем добавления HTTP-заголовка в Apache httpd.conf:

RequestHeader set X-Request-Start "%t"

New Relic упоминает, что:

Для сегмента очереди запросов оператор сайта может предоставить больше экземпляров приложения.

Однако мы видели, что добавление новых экземпляров приложения (то есть веб-узлов) не влияет на время ожидания запросов - оно остается постоянным. Мы видим, что это измеряется примерно на 250 мс.

Какие факторы влияют на длину очереди запросов и как ее уменьшить?

[1] http://support.newrelic.com/help/kb/features/tracking-front-end-time

Я думаю, что лучший способ сделать это - увеличить параметры Server Limit и Max Clients в Apache Config.

Это определяет, сколько потоков Apache может обрабатывать одновременно. Если у вас установлено значение «Максимальное количество клиентов», равное 100, Apache может обрабатывать до 100 запросов одновременно.

Вероятно, также стоит отметить, что Apache хорош для небольших файлов (текст, возможно, CSS / JS и т. Д.), Но не так хорош для больших файлов, таких как изображения, видео, флэш и т. Д. Это потому, что каждый из них требует нового запроса (если только вы используете Keep-alive, но это не слишком улучшает его). Таким образом, если у вас есть страница с 49 внешними ресурсами (всего 50 запросов), загрузка которой занимает 1 секунду, а максимальное количество клиентов установлено на 100, вы можете обрабатывать только два просмотра страницы в секунду, прежде чем запросы начнут ставиться в очередь.

Вы можете обойти это разными способами, попробуйте выгрузить свой контент в CDN (цена начинается примерно с 0,10 доллара за ГБ, но если у вас высокая передача данных, возможно, стоит связаться с Edgecast или Akami, поскольку их цены намного дешевле в навалом). Это означает, что вашему серверу не нужно беспокоиться о каких-либо статических ресурсах, необходимых для загрузки страницы, поэтому в нашем примере выше вы теперь просматриваете до 100 страниц в секунду, прежде чем запросы начнут ставиться в очередь.

Если вы не хотите раскошелиться на CDN, я бы предложил получить два IP-адреса на вашем сервере и подключить один к Apache, а другой к NGINX. NGINX - это очень высокопроизводительный сервер, способный обрабатывать в тысячи раз больше соединений, чем Apache, NGINX не использует очередь запросов, как Apache, потому что он не блокирует. К сожалению, NGINX не обладает всеми функциями Apache, вы не можете, например, запускать PHP напрямую через NGINX, не проксируя Apache / FCGI / HipHop и т. Д.

В качестве дополнения к этому, в вашем вопросе вы говорите «веб-узлы», был бы я прав, если подумал, что вы используете Apache в качестве внешнего балансировщика нагрузки / прокси-сервера для этих узлов? Если это так, я предлагаю вам протестировать что-то вроде NGINX, Varnish, HAProxy и т. Д., Поскольку они намного лучше подходят для таких вещей и обработки одновременных подключений.

-
РЕДАКТИРОВАТЬ:
Я подумал, что это может вас заинтересовать в отношении внешних серверов LB.
Мы использовали Apache в качестве внешнего прокси для 16 узлов приложений, разделенных на два сервера. Прокси-сервер работал на четырехъядерном сервере Intel Core i5 (так что ни в коем случае не ниже спецификации). Мы начали замечать параболическую зависимость между количеством запросов в секунду и временем ответа. Примерно при 2000 запросов в секунду загрузка ЦП резко возрастет, и каждый ответ будет занимать около 800 мсек, при 3000 об / с каждый ответ будет занимать около 2 секунд. Мы перешли на NGINX и достигли 5000 об / с, при этом добавив в среднем только 50 мсек к задержке, а загрузка процессора составила четверть от того, что было с Apache.
Очевидно, это полностью зависит от вашей ситуации, от того, что вы делаете и какие ресурсы у вас есть, но я просто подумал, что дам вам свое мнение =)

Я должен задать очевидный вопрос: в документации указано, что вы должны использовать http-заголовок X-Queue-Start (или X-Queue-Time), но вы упомянули, что используете X-Request-Start. Вы добавляете правильный заголовок?