[Обновлено, чтобы быть более лаконичным!]
Я новичок в мире оптимизации веб-серверов для большого трафика, но теперь я вникаю в это.
В понедельник наш веб-сервер был отключен - у нас был огромный всплеск трафика (85000 посетителей за час или около того), и хотя мы запускали Varnish и nginx (которые выполняют свою работу должным образом), сторона Apache действительно боролась. - это динамический контент, который создается по некоторым запросам.
На сервере сейчас 8 ГБ ОЗУ, это будет обновлен до 32 ГБ очень скоро, так что мне действительно нужна помощь в настройке системы 32 ГБ. В настоящее время работает 64-битный centos.
Я исследовал настройку varnish и nginx, они в порядке - разумные настройки (статический контент, выдаваемый непосредственно nginx, множество динамических вещей, выдаваемых лаком, и если он не в лаке, запрос передается в apache).
Итак, что касается Apache ... мы используем модуль prefork MPM, каждый процесс apache, кажется, использует МНОГО оперативной памяти:
Топ 3:
S 48 20961 2965 0 75 0 187128 128307 ? ? 00:05:25 httpd
S 48 20959 2965 0 75 0 249788 143435 ? ? 00:05:55 httpd
S 48 18581 2965 0 75 0 314564 157747 ? ? 00:06:40 httpd
Внизу 3:
S 0 2965 1 0 78 0 15132 89017 stext ? 00:00:00 httpd
S 48 20947 2965 0 75 0 38492 93001 ? ? 00:00:00 httpd
S 48 20945 2965 0 75 0 43300 93897 ? ? 00:00:01 httpd
Я не совсем уверен, но я думаю, что один процесс = один клиент = одно соединение с одним браузером человека. Думаю, мой первый вопрос: может ли кто-нибудь подтвердить это? Да, мы используем php и zend framework, MySQL как серверную часть базы данных на одном сервере.
Текущая конфигурация (в настоящее время у сервера 8 ГБ оперативной памяти):
MaxKeepAliveRequests 100
KeepAliveTimeout 2
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 200
MaxClients 200
MaxRequestsPerChild 500
</IfModule>
Я считаю, что в настоящее время Apache теоретически может попытаться использовать около 63 ГБ оперативной памяти в худшем случае с этой конфигурацией. Например, 315 МБ процесс * 200 макс. Клиентов = много оперативной памяти. Я не совсем уверен, что это так работает, но если кто-то может это подтвердить, это поможет!
Я бы хотел получить несколько советов о том, на что мне следует обратить внимание - мы хотим, чтобы сервер мог обрабатывать новый всплеск запросов в любое время и использовать всю новую оперативную память, которую мы получаем. . Я отвечу на оптимизацию MySQL в другом вопросе, если не смогу разобраться сам, но вот конфу на всякий случай, которая имеет значение: http://pastebin.com/GbJU7AxY
Ура! Джон.
Что такое 85 000 посетителей в день? Уникальные посетители, общее количество обращений по HTTP, что-то еще?
Varnish должен иметь возможность обрабатывать тысячи обращений в секунду при небольшом количестве ЦП и памяти, если запросы могут обслуживаться из кеша. Особенно когда используется Slashdotted, поскольку большинство людей будут искать точно такой же контент. Однако это требует тонкой настройки. По умолчанию он довольно консервативен, поскольку мало знает о передаваемом контенте. Он принимает решения на основе заголовков, которые он видит, и простого набора правил. Например, по умолчанию Varnish кэширует объекты на 2 минуты, но только если нет печенья присутствуют в запросе, а TTL объекта> 0, и ... и т.д. Проверьте VCL по умолчанию (в частности, vcl_recv и vcl_fetch), чтобы определить логику по умолчанию и убедиться, что вы ее понимаете.
Итак, один файл cookie Google Analytics, установленный в вашем домене, вызывает все запросы для передачи на серверную часть, даже если файлы cookie GA обрабатываются не вашим внутренним сервером, а JavaScript-кодом Google. Приложение WordPress устанавливает все виды файлов cookie, большинство из которых применимо только к динамическому контенту, который возвращается браузером при каждом запросе. Если ваша страница содержит 49 статических ресурсов и 1 динамическую страницу, это означает, что ни один из этих статических ресурсов не будет кэшироваться, потому что запросы содержат cookie, которые вам не нужны. Должен пройти только файл cookie динамического запроса. Такая ошибка по существу отключает Varnish. Кроме того, важны различные HTTP-заголовки управления кешем (и связанные с ним), которые возвращает ваш код. Если ваше приложение утверждает, что объект, который Varnish извлекает из серверной части, уже истек, например, с заголовком Expires в прошлом, Varnish не будет кэшировать этот объект.
Другими словами, вам нужно настроить свое приложение для выдачи правильных заголовков, чтобы клиенты (и Varnish, и браузер) могли кэшировать возвращаемый контент. Все, что вы не можете исправить в своем приложении, вы можете переопределить в VCL Varnish.
Например, вот мой код для удаления различных файлов cookie отслеживания на стороне клиента от доступа к серверу. Это принадлежит vcl_recv
:
# Remove tracking cookies. The server doesn't need to see them.
if (req.http.Cookie) {
# Remove has_js and Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js|sifrFetch)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
# Remove cookie header if empty
if (req.http.Cookie == "") {
remove req.http.Cookie;
}
}
Точно так же я удаляю входящие файлы cookie на определенные пути, чтобы сделать эти запросы кешируемыми:
if ( req.url ~ "^/cms/cms_files/(?:css|img|js)/" || #CMS1
req.url ~ "^/site_files/(?:css|img|imgc|js|swf|uploads|xml/.+\.xml$)" || #CMS1
req.url ~ "^/(?:images|stylesheets|javascripts|swf|site_files/js_libs|site/image|favicon\.ico$|robots\.txt$)" || #CMS2
( req.http.host ~ "(?:shop\.example\.com|www\.example\.nl)" && #Magento
req.url ~ "^/(?:404|js|media|skin|favicon\.ico$)" ) || #Magento
) {
unset req.http.cookie;
}
Я использую аналогичную строфу в vcl_fetch, с unset beresp.http.cookie;
вместо этого, чтобы бэкэнд не устанавливал файлы cookie на пути, которые мне не нужны.
Вы могли бы добавить заголовки отладки которые дают вам информацию о том, как лак обрабатывал запросы. Просмотрите их с помощью Firebug, и вы поймете намного больше о своем приложении. Еще один хороший источник информации - это Лаковая книга. Например, см .: https://www.varnish-software.com/static/book/VCL_Basics.html
Большая часть нашего динамического контента кэшируется на 60 секунд, чего достаточно, чтобы парировать давку. Если вам требуется какой-то индивидуальный контент, но большая часть контента на ваших страницах довольно статична, загляните в Varnish ESI (edge-side-includes), который позволяет вам указывать разные TTL кеша для разных частей страницы.
Теперь, когда вы сократили количество внутренних запросов до минимума, оптимизируйте эти запросы. Профилируйте свое приложение, найдите и устраните проблемы.
Вы правы: MaxClients x (maximum physical memory per Apache process) = (total memory Apache can use)
Однако это физическая память, а не упомянутая вами виртуальная память. Вверху res столбец показывает физическую память, используемую каждым процессом. Каждый процесс Apache превращается в самые большие скрипты, которые запускает ваш сайт. Ограничьте MaxClients суммой, которую может обработать ваш сервер. Нет смысла принимать запросы, для которых у вас нет ресурсов. Как только вы начнете менять местами, вы проиграли. Увеличьте количество процессов (серверов), которые выполняет предварительный вызов Apache, поскольку разветвление - это тяжелая операция, которую вы хотите выполнить, когда он уже занят. Строка ServerLimit избыточна. Либо отключите KeepAlive, либо установите его на 1-2 секунды.
Если вы обслуживаете много статических ресурсов, подумайте о переходе с mod_php на PHP-FPM. Это упрощает ваши процессы Apache.