Не спасовать перед лавиной: Подготавливаем веб-сервер к высоким нагрузкам. Загружайте только нужные модули. Отключение разрешения имён хостов


Apache — популярный веб-сервер в интернет, он обслуживает множество серверов и сайтов. Часто возникает необходимость увеличить производительность веб-сервера. Наверное лучший способ это сделать — перейти к схеме frontend+backend, но это может потребовать достаточно серьезных изменений в приложении (например, у вас наверняка отвалятся всяческие индикаторы прогресса аплоада файлов:).
Другой способ — просто увеличить производительность сервера — поставить более быстрый процессор и больше памяти.
Однако и первое и второе требует много времени и ресурсов, так что на первое время можно попробовать ускорить apache путем оптимизации его конфигурации. Существуют оптимизации, которые можно применить только при пересборке apache, другие же можно применять без перекомпиляции сервера.

Загружайте только необходимые модули

Apache — модульная программа, большая часть функций которой реализуется в модулях. При этом эти модули могут быть как вкомпилированы, так и собраны в виде DSO — динамических библиотеках. Большинство современных дистрибутивов поставляет apache с набором DSO, так что не нужные модули можно легко отключить без перекомпиляции.
Запускайте apache только с необходимыми модулями, чтобы уменьшить потребление памяти. Если вы решили скомпилировать apache самостоятельно, то либо тщательно подходите к выбору списка модулей, которые вы включите, либо компилируйте их как DSO используя apxs в apache1 и apxs2 в apache2. Для того чтобы отключить ненужные DSO-модули, достаточно закомментировать лишние строчки LoadModule в httpd.conf. Apache со статически скомпилированными модулями будет потреблять чуть меньше памяти, однако вам придется каждый раз его перекомпилировать для изменения списка модулей.

Выберете подходящий MPM

В apache каждый запрос обрабатывается в своем процессе или потоке. При компиляции apache позволяет выбирать один из нескольким MPM (Multi-processing module), которые отвечают за прослушивание портов, прием запросов и раздачу этих запросов дочерним процессам или потокам, в которых эти запросы будут обработаны.
Выбор MPM зависит от нескольких факторов, таких как наличие поддержки потоков в ОС, количества свободной памяти, а также требований стабильности и безопасности.
Если безопасность очень важна, следует выбрать peruser MPM, пожертвовав производительностью.
Если важна именно производительность, то выбор ограничивается двумя mpm: prefork и worker.
Worker - поточный MPM, т.е. в нем каждый запрос обслуживается в отдельном потоке одного из дочерних процессов. Потоки — более легкие для ОС объекты, чем процессы, они более эффективно используют память и переключения контекста для них происходят быстрее. Однако, из-за того что каждый поток имеет доступ ко всей памяти процесса, worker mpm более подвержен сбоям: сбой одного потока может повлечь падение всего процесса, в котором находился этот поток (именно поэтому worker mpm запускает несколько дочерних процессов с несколькими потоками в каждом).
Perfork - mpm использует несколько дочерних процессов, каждый дочерний процесс обрабатывает одно подключение. Из-за того что процесс — более тяжелая структура, он использует немного больше ресурсов, зато он менее подвержен сбоям — обработка каждого отдельного запроса не зависит от других процессов.
К сожалению, для смены mpm требуется перекомпиляция apache. Тут проявляют свои достоинства source-based дистрибутивы: вы можете легко перекомпилировать apache и все зависимые от него пакеты, не превратив систему в свалку. Бинарные дистрибутивы выходят из этой ситуации по-разному. Например в RHEL в apache rpm находится сразу две версии apache — с worker и prefork mpm (prefork используется по умолчанию). Однако worker mpm не поддерживает php. Так что если вы хотите php и worker mpm вам придется компилировать его самостоятельно либо искать сторонние репозитории.

DNS lookup

Директива HostnameLookups включает reverse DNS запросы, так что в логи будут попадать dns-хосты клиентов вместо ip-адресов. Разумеется, что это существенно замедляет обработку запроса, т.к. запрос не обрабатывается пока не будет получит ответ от DNS-сервера. Поэтому следите чтобы эта директива всегда была выключена (HostnameLookups Off), а если вам все-таки нужны dns-адреса, вы можете узнать их позже, прогнав лог в утилите logresolve (которая поставляется с apache).
Кроме того, следите чтобы в директивах Allow from и Deny From использовались ip-адреса а не доменные имена. Иначе apache будет делать два dns запроса (обратный и прямой) чтобы убедиться что клиент-тот за кого себя выдает.

AllowOverride

Если директива AllowOverride не установлена в ‘None’, apache будет пытаться открыть.htaccess файлы в каждой директории которую он посещает и во всех директориях выше нее. Например:

DocumentRoot /var/www/html AllowOverride all

Если будет запрошен /index.html, apache попытается открыть (и интерпретировать) файлы /.htaccess, /var/.htaccess, /var/www/.htaccess, и /var/www/html/.htaccess. Это увеличивает время обработки запроса. Так что, если вам нужен.htaccess только для одной директории, разрешайте его только для нее:

DocumentRoot /var/www/html AllowOverride None AllowOverride all

FollowSymLinks и SymLinksIfOwnerMatch

Если для директории включена опция FollowSymLinks, сервер будет следовать по символическим ссылкам в этой директории. Если для директории включена опция SymLinksIfOwnerMatch, apache будет следовать по символическим ссылкам только если владелец файла или директории, на которую указывает эта ссылка совпадает с владельцем указанной директории. Так что при включенной опции SymLinksIfOwnerMatch apache делает больше системных запросов.
Кроме того, дополнительные системные запросы требуются когда FollowSymlinks НЕ УСТАНОВЛЕН. Т.о. наиболее оптимальная ситуация для производительности — когда опция FollowSymlinks включена.

Content Negotiatio

Старайтесь избегать content negotiaion.

MaxClients

Директива MaxClients устанавливает максимальное количество параллельных запросов, которые будет поддерживать сервер. Apache не будет порождать больше процессов/потоков чем MaxClients. Значение MaxClient не долно быть слишком маленьким (иначе много клиентов останутся необслуженными), но и не стоит устанавливать слишком большое количество — лучше не обслужить часть клиентов чем исчерпать все ресурсы, залезть в своп и умереть под нагрузкой. Хорошим может быть значение MaxClients = количество памяти выделенное под веб-сервер / максимальный размер порожденного процесса или потока. Для статических файлов apache использует около 2-3 Мб на процесс, для динамики (php, cgi) — зависит от скрипта, но обычно около 16-32 Мб.

Если сервер уже обслуживает MaxClients запросов, новые запросы попадут в очередь, размер которой устанавливается с помощью директивы ListenBacklog.

MinSpareServers, MaxSpareServers, и StartServers

Т.к. создание потока, и особенно процесса — дорогая операция, apache создает их заранее. Директивы MaxSpareServers и MinSpareServers устанавливают как много процессов/потоков должны ожидать в готовности принять запрос (максимум и минимум). Если значение MinSpareServers слишком маленькое и неожиданно приходит много запросов, apache вынужден будет создавать много новых процессов/потоков, что создаст дополнительную нагрузку в этой стрессовой ситуации. С другой стороны, если MaxSpareServers слишком велико, apache будет сильно нагружать систему этими процессами, даже если количество клиентов минимально.
Постарайтесь установить такие MinSpareServers и MaxSpareServers, чтобы apache не создавал более 4 процессов/потоков в секунду. Если он создаст более 4, в ErrorLog будет помещено сообщение об этом. Это — сигнал того что MinSpareServers слишком мало.

MaxRequestsPerChild

Директива MaxRequestsPerChild устанавливает сколько запросов может обработать один дочерний процесс/поток прежде чем он будет завершен. По умолчанию значение этой директивы установлено в 0, что означает что однажды созданный процесс/поток не будет завершен никогда (ну кроме случаев остановки сервера или краха этого процесса/потока). Рекомендую установить MaxRequestsPerChild равное какому-нибудь достаточно большому числу (несколько тысяч). Это не создаст излишней нагрузки, связаной с тем что apache будет вынужден создавать новые дочерние процессы, в то же время это поможет избавиться от проблем с утечкой памяти в дочерних процессах (что очень возможно например если вы используете нестабильную версию php).

KeepAlive и KeepAliveTimeout

KeepAlive позволяет делать несколько запросов в одном TCP-подключении. Это особенно полезно для html-страниц с большим количеством изображений. Если KeepAlive установлен в Off, то для самой страницы и для каждого изображения будет создано отдельное подключение (которое нужно будет обработать master-процессу), что плохо и для сервера и для клиента. Так что для подобных случаев рекомендуется устанавливать KeepAlive в On. Для других применений (например для download-сервера) KeepAlive может быть бесполезен и даже вреден, т.к. при включенном KeepAlive сервер закрывает соединение не сразу, а ждет KeepAliveTimeout секунд нового запроса. Для того чтобы процессы не висели слишком долго в бесполезном ожидании, устанавливайте KeepAliveTimeout достаточно малым, около 5-10 секунд обычно достаточно.

Сжатие

HTTP-сжатие было определено в стандарте HTTP/1.1, и сейчас все современные клиентские программы и практически все сервера его поддерживают. Сервер может отдавать ответ в gzip или deflate, а клиентская программа незаметно для пользователя разжимает данные. Это уменьшает количество передаваемого трафика (до 75%), но конечно же повышает использование процессора.
Однако если ваш сервер посещает много клиентов с медленным подключение, сжатие может снизить нагрузку с вашего сервера из-за того что сервер сможет быстрее передать сжатый ответ и освободить ресурсы, занятые дочерним процессом. Особенно сильно этот эффект может быть заметен если у вас быстрый процессор, но мало памяти.
Кеширование конфигурируется директивами модуля mod_deflate. Имейте в виду, что не следует устанавливать степень сжатия gzip более 4-5 — это потребует существенно большего времени CPU, а эффект будет достаточно невелик. Ну и разумеется не нужно пытаться сжать изображения в jpg, gif и png, музыку, видео файлы и все другие бинарные файлы, которые уже и так хорошо сжаты.

|

Apache – очень производительный веб-сервер. Чтобы упростить начальную настройку, он предлагает большое количество предварительно установленных модулей. Потому Apache отлично подходит для развертывания новых проектов – с его помощью можно быстро настроить надежную среду производства. Однако по мере роста сайта (и, соответственно, объема трафика) вы можете столкнуться с проблемами.

Это руководство поможет увеличить производительность Apache на вашем виртуальном сервере.

1: Отключите ненужные модули

В Ubuntu и Debian-подобных системах есть каталоги etc/apache2/mods-enabled и /etc/apache2/mods-available/. В последнем хранится список всех модулей, установленных на данном сервере. А в каталоге mods-enabled находятся модули, включенные в данный момент.

Ситуация по умолчанию может отличаться на каждом сервере. Предположим, что на сервере по умолчанию включено 17 модулей. Как правило, этого слишком много для среднестатистического приложения. Кроме того, довольно сложно сразу определить ненужные модули, которые можно отключить, так как отдельные модули являются зависимостями других.

Для начала рекомендуется сохранить список модулей, активных по умолчанию, чтобы в дальнейшем иметь возможность использовать его для восстановления стандартных параметров. Затем вы можете просто отключить все ненужные модули по одному, перезапуская Apache после отключения каждого модуля, чтобы убедиться, что в системе не возникло ошибок.

В Ubuntu и Debian модули отключаются с помощью этой команды:

sudo a2dismod autoindex

Отдельные модули потребляют очень много ресурсов; если вы не используете следующие модули, просто отключите их:

  • Rewrite
  • Python
  • Rack / Ruby / Passenger

Не все эти модули включены по умолчанию, однако ситуация индивидуальна для каждого сервера.

Примечание: Обычно Apache по умолчанию включает модуль rewrite, хотя его можно заменить модулем alias. Если вашему приложению подходит alias, отключите rewrite – это один из самых тяжелых модулей. Чтобы перейти с rewrite на alias, обратитесь к документации модуля . Даже если вы не сможете полностью отключить rewrite, вы сможете оптимизировать отдельные правила модуля.

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

К примеру, вы можете получить такую ошибку:

Syntax error on line 6 of /etc/apache2/sites-enabled/site1:
Invalid command "DAVLockDB", perhaps misspelled or defined by a module not included in the server configuration
Action "configtest" failed.

Это значит, что отключенный модуль необходим для корректной работы веб-сервера. Включите его.

sudo a2enmod dav_fs

2: Переместите код

На сайтах PHP часто используется популярный модуль mod_php, а на сайтах ruby – Passenger Phusion (модули mod_rails или mod_rack).

Проблема в том, что код С для интерпретатора этого языка вложен в Apache, а это требует больше памяти для просмотра каждой страницы. Если популярная страница вашего сайта получает 30 HTTP-запросов, один из них будет для динамической страницы, а остальные 29 – для статических ресурсов (изображений, css и javascript). Чтобы увеличить производительность Apache, можно исключить 29 запросов, которые не обслуживают динамический контент.

Включение модуля mod_php может привести к тому, что на обслуживание одного дочернего процесса Apache будет требоваться 100 Мб RAM. Чем больше процессов Apache будет запущено на сервере, тем сложнее их будет обрабатывать.

Чтобы устранить эту проблему, можно использовать такие инструменты:

  • Для PHP можно установить php-fpm, который является отдельным процессом на основе протокола fastcgi.
  • В Python используйте uWSGI или gnunicorn
  • Для Rails используйте Unicorn .

Сначала запускается процесс для PHP, Python или Ruby, а затем Apache перенаправляет вызовы динамического контента на этот процесс вместо того, чтобы пытаться обработать его с помощью вложенного кода.

После удаления модуля mod_php размер процессов Apache может измениться с 90-120 Мб до всего 10 Мб. Весь динамический контент обслуживается всего двумя процессами на бэкэнде.

3: Ограничьте количество процессов Apache

Многие операционные системы используют конфигурации по умолчанию, которые не очень подходят маленьким серверам – 25 дочерних процессов. Если каждый дочерний процесс Apache требует 120 Мб RAM, то сервер будет тратить 3 Гб только на Apache.

Веб-браузер одного пользователя может запрашивать 4 элемента сайта за раз, а значит всего 7-8 человек способны перенагрузить сервер. Веб-страницы зависают или грузятся очень медленно.

Сервер часто поддерживает такие мертвые процессы Apache в активном состоянии, пытаясь обслужить запрашиваемый контент, а это снижает количество доступных процессов для обслуживания пользователей и объем памяти. В результате вы получаете плохой пользовательский опыт.

Определите, сколько RAM требуется вашему приложению и сколько памяти остается, а затем выделите большую часть оставшейся памяти для Apache.

К примеру, у вас есть три процесса php-fpm для обработки динамического контента, где каждый процесс использует до 70 Мб памяти, а также сервер MySQL, который берет до 120 Мб RAM. В результате получается, что приложение использует 330 Мб памяти. Если у вас маленький сервер, вы можете выделить для Apache около 150 Мб памяти.

Когда веб-сервер Apache запущен, запустите команду top. Она выводит множество полезной информации. Ниже приведен фрагмент ее результата:

top -bn 1
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
[...]
15015 www-data 20 0 232m 9644 1900 S 0.0 1.6 0:00.02 apache2
15016 www-data 20 0 232m 9644 1900 S 0.0 1.6 0:00.01 apache2
15017 www-data 20 0 232m 9644 1900 S 0.0 1.6 0:00.02 apache2

Найдите значение в столбце RES для Apache (например, 9 644) и запишите его. На данный момент веб-сервер использует почти 10 Мб памяти. Если ограничить количество дочерних процессов Apache до 15, 150 Мб выделенной памяти будет вполне достаточно.

Отредактируйте конфигурационный файл Apache (в Ubuntu и Debian это /etc/apache2/apache2.confand) и найдите раздел mpm_prefork_module. Найдите строку MaxClients и введите 15, а затем сохраните файл и перезапустите веб-сервер.


StartServers 3
MinSpareServers 3
MaxSpareServers 5
MaxClients 30
MaxRequestsPerChild 0

По умолчанию значение MaxClients может быть очень большим. Его нужно уменьшить.

Когда количество клиентов достигает предела, новые клиенты получат ошибку. Перезагрузив страницу, они смогут получить доступ к сайту.

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

В некоторых ситуациях меньшее количество дочерних процессов помогает увеличить производительность сервера.

Часто в конфигурациях Apache используется предварительная настройка prefork mpm, которая считается безопасной и подходящей для PHP и других языков.

Если вы избавитесь от внешних модулей (PHP или Rails), вы можете рассмотреть worker MPM в качестве альтернативы.

Чтобы включить этот модуль, введите:

sudo apt-get install apache2-mpm-worker
The following packages will be REMOVED:
apache2-mpm-prefork libapache2-mod-php5
The following NEW packages will be installed:
apache2-mpm-worker
0 upgraded, 1 newly installed, 2 to remove and 2 not upgraded.
Need to get 2,284 B of archives.
After this operation, 8,718 kB disk space will be freed.
Do you want to continue ?

Внимание! В Ubuntu при установке модуля worker удаляется prefork mpm, mod_php и другие несовместимые модули.

Tags:

После ввода в строй динамического веб-сервера на базе apach + php + postgresql (да и на базе других систем тоже, если честно), вебмастер часто обнаруживает, что производительность системы начинает с большей или меньшей активностью стремиться к нулю, порой его достигая при наплывах посетителей. Стандартными действиями вебмастера при этом являются лихорадочное чтение документации, поиск в Интернете всяческих полезных советов, общение в форумах и прочие телодвижения, типичные для «компьютерного аврала». При этом очень часто находятся какие-то обрывки информации, ответы из серии «у меня заработало, почему у тебя не работает не знаю», противоречивые советы и ссылки на мегабайтные исходники, разбор которых грозит затянуться на несколько лет…

Поэтому ниже предпринята попытка в компактном виде изложить те вещи, которые наиболее значительно влияют на производительность сервера. Нельзя сказать, что этот список является полным и законченным, но он может послужить неплохой пищей для размышлений. А если у вас есть какие-то свои наработки и «идеи по поводу» — пишите автору, он постарается учесть их в следующей редакции этой статьи…

Настройка php

Настройка php, по большому счету, сводится к включению persistent connections и, соответственно, использованию pg_pconnect() вместо pg_connect() в скриптах. Для этого в файле php.ini надо указать pgsql.allow_persistent = on В некоторых форумах встречалась рекомендация установить еще и pgsql.auto_reset_persistent = on для определения «битых» соединений, но то ли «битые соединения» встречаются очень редко, то ли они проявляются как-то незаметно… Словом, этого можно и не делать. Ограничений по количеству соединений в php можно не устанавливать, оставив
pgsql.max_persistent = -1
pgsql.max_links = -1

Эффект от перехода на постоянные соединения очень заметен, особенно на посещаемых сайтах. Загрузка сразу падает процентов на двадцать-тридцать, а то и больше! Только не пугайтесь обнаруживая в top’е кучу postres’ов в состоянии sbwait…

Настройка postgresql

Настройка postgresql осуществляется с помощью редактирования файла postgresql.conf и последующего перезапуска постмастера. Несмотря на то, что некоторые параметры можно менять «на лету», практика показала, что полный перезапуск позволяет намного точнее и быстрее отследить влияние тех или иных изменений конфигурации на поведение системы в целом, так что имеет смысл использовать именно этот метод.

Настройка shared_buffers в postgres’е очень важна. Чем больше памяти ему выделено, тем больше данных он сможет использовать не обращаясь к диску. Но если памяти выделить слишком много, то другим процессам ее может не хватить и они будут использовать файл подкачки. Поэтому с настройкой этого параметра придется поэкспериментировать — помимо всего прочего, очень многое зависит от конкретики вашего сайта, в частности от того, насколько часто запрашиваются одни и те же данные. В качестве стартовой точки можно попробовать выделить postgres’у 40% памяти, если он работает на одной машине с веб-сервером, и 70%, если это выделенный сервер баз данных. Только не забудьте, что до того, как указывать количество памяти в файле postgresql.conf, вам надо настроить операционную систему, чтобы она разрешила эту память забрать, иначе postgresql просто не запустится, написав в лог, что не удалось получить требуемую память. О том как настроить выделение необходимой памяти в разных ОС подробно написано в документации postgresql. Эта память выделяется один раз при старте сервера.

Следующий полезный параметр — sort_mem. Эта память используется для сортировки полученных наборов данных, и большое ее количество полезно, если ваши запросы часто используют select … order by… Но с этим параметром надо быть очень осторожным — мало того, что указанное вами количество памяти выделяется каждому процессу, так оно еще и может выделяться несколько раз для сложных запросов! Так что с этим параметром тоже стоит «поиграть» — попробуйте изменять его значения в диапазоне, скажем, от 1 Мб до 128 Кб. Причем иногда результаты бывают парадоксальными — уменьшение памяти ведет к повышению производительности, по всей видимости, из-за создания множества маленьких временных файлов, которые операционная система успешно кеширует в свободной памяти.

Если задачи, выполняющиеся на сервере не являются критичными и возможная потеря нескольких записей при аварии вас не пугает, то стоит также отменить принудительную запись на диск результатов каждой транзакции. Делается это указанием fsync = false. При этом результаты ваших изменений будут хранится в памяти и записываться на диск целыми блоками, что позволит достаточно заметно увеличить производительность. Но, как было отмечено выше, если вдруг сервер «упадет», то результаты нескольких последних обновлений могут быть утеряны.

Очень сильно влияет на скорость работы грамотное индексирование таблиц. Про индексы можно писать (и уже написано) много, но основной принцип — индексировать надо те поля, которые используется для выборки данных (проверяются в where). Составные индексы (в которых используется несколько полей) работают, если отбор происходит с условием and, если используется or, то надо создавать несколько отдельных индексов.

Однако для маленьких таблиц (скажем, до 500 строк) перебор почти всегда оказывается быстрее, чем использование индексов. Тут можно применить маленькую хитрость: в postgresql.conf указать enable_seqscan = false (это запретит перебор для тех таблиц, у которых есть индексы) и удалить все индексы в маленьких таблицах (индексы, автоматически создаваемые для первичных ключей, можно удалить, используя drop constraint).

Неплохой выигрыш в производительности может дать и оптимизация самих sql запросов, особенно тех, которые используются чаще всего. Для того, чтобы их вычислить можно в скриптах перенумеровать все запросы и перед каждым вызовом pg_query() записывать в лог (или в таблицу) номер запроса. А потом просто проанализировать лог… Для того, чтобы посмотреть как будет выполняться запрос можно (нужно!) использовать команду explain. Учтите, что в некоторых случаях даже простое изменение порядка следования условий выборки в секции where может изменить план выполнения запроса!

В некоторых случаях может помочь и использование представлений (views). Дело в том, что при выдаче «обычного» sql запроса сервер его анализирует, создает план выполнения и потом выполняет. А если используется представление, то анализ и составление плана производится только при его создании. Если запросы выполняются часто, то сэкономленное время работы процессора может оказаться весьма заметным. Не говоря уже о том, что запросы в скриптах станут намного короче и нагляднее…

Практически во всех руководствах (и в документации postgresql) можно встретить рекомендации регулярно запускать vacuum analyze, для сжатия таблиц. Рекомендация правильная и полезная, но недостаточная. Практика показала, что без более-менее регулярных запусков vacuum full analyze производительность системы постепенно падает, причем чем дальше, тем больше. Разница между vacuum и vacuum full заключается в том, что full физически переписывает на диске всю таблицу таким образом, чтобы в ней не оставалось «дырок» от удаленных или обновленных записей. Но его недостаток в том, что во время работы таблица полностью блокируется, что может привести к проблемам на популярном сервере — начнет скапливаться очередь запросов, ожидающих доступа к базе, каждый запрос требует памяти, память кончается, начинается запись в swap, из-за отсутствия памяти сам vacuum тоже начинает использовать swap и все начинает работать очень-очень медленно.

Тут можно использовать следующий трюк — во время работы vacuum’а перенаправлять посетителей на страничку с пояснениями, что идет профилактика и сервер восстановит свою работу через несколько минут. При использовании веб-сервера apache это легко делается с помощью mod_rewrite: ваш оптимизирующий скрипт при запуске создает, а при окончании работы удаляет файл /home/site/optimizer.pid, а в apache включается mod_rewrite и указывается
rewritecond /home/site/optimizer.pid -f
rewriterule .* /optimization_message.html

Для того чтобы уменьшить время, в течение которого посетители не могут добраться до вашего сайта, можно перенаправлять посетителей только в то время, когда оптимизируются большие и частоиспользуемые таблицы, а остальные «чистить» паралльно с работой сайта. Если данные в базе обновляются очень часто, то можно, скажем, каждый час запускать vacuum analyze, а раз в сутки — vacuum full analyze. Как правило, «время недоступности» сервера при таком подходе можно сократить до одной-двух минут даже на очень больших сайтах.

Кроме того, надо учесть, что vacuum не оптимизирует индексы, поэтому после отработки vacuum full analyze стоит запускать еще и reindex.

Разумеется, очень большое влияние на производительность оказывает и структура вашей базы данных, но эта область очень сильно зависит от конкретной задачи и в этой статье затрагиваться не будет.

Настройка apache

Конфигурационный файл apache, как правило, находится в /usr/local/apache/conf/httpd.conf, а заставить сервер его перечитать можно с помощью проргаммы /usr/local/apache/bin/apachectl.

Основной целью дальнейших рекомендаций является определение и ограничение количества «апачей», выполняющихся в каждый момент времени (предполагается, что сам сервер у вас уже настроен и работоспособен). Дело в том, что (условно) на каждого посетителя сайта «тратится» процесс apache, и каждый такой процесс расходует память и процессорное время. Поэтому если у вас будет слишком много запущенных серверов, то оперативной памяти не хватит, а использование swap’а сильно замедляет работу сайта. С другой стороны, если запущенных серверов мало, то при заходе пользователя будет тратиться время на создание нового процесса, что опять же приводит к задержкам и расходу процессорного времени.

Из вышесказанного ясно, что с одной стороны желательно всегда иметь некоторый запас запущенных серверов для обслуживания посетителей, а с другой — надо убивать лишние сервера, чтобы не занимать слишком уж много памяти. Понятно, что конкретные цифры зависят от посещаемости вашего сайта и доступных ресурсов, поэтому приводимые ниже цифры стоит использовать только как основу, корректируя их по необходимости.

Максимальное количество «апачей», которые могут быть запущены одновременно определяется параметром maxclients. Это число должно чуть-чуть превышать максимальное количество посетителей, которые могут в какой-то момент времени оказаться у вас на сайте. В то же время, если желающих к вам попасть много, а ресурсов сервера для их обслуживания не хватает, то излишне высокое число запущенных серверов только затормозит всю работу. Поэтому желательно установить какое-то разумное ограничение, скажем 150 или 200.

Время, в течение которого сервер ждет откликов от клиента определяется параметром timeout. Обрывы связи иногда случаются и если браузер посетителя обратился к вашему серверу, не получил ответа и послал повторный запрос (скажем, пользователь нажал reload), то у вас запустятся два «апача», причем один из них будет просто висеть и в течение указанного времени ждать, когда посетитель подтвердит свое желание посмотреть страничку. По умолчанию этот параметр установлен в 300 секунд, но значительно более эффективным оказалось понизить его до 30.

Включение поддержки keepalive может заметно облегчить жизнь. Дело в том, что в «обычном» режиме для передачи каждого файла клиенту требуется установить соединение, и если у вас на страничке, например, есть 10 картинок, то придется устанавливать и разрывать 10 соединений для их передачи. А в режиме keepalive сервер после передачи файла соединение не разрывает и последующие запросы от этого клиента обрабатывает, используя уже установленное соединение. Таким образом экономится время на установку и разрыв соединений, причем для популярных сайтов эта разница может быть очень заметна!

Для keepalive соединений, точно также как и для обычных, надо установить timeout с помощью параметра keepalivetimeout. Так как сервер, установивший соединение с клиентом, недоступен для других клиентов пока соединение не будет разорвано, слишком большое значение может привести к куче серверов, ничего не делающих и просто ждущих не захочет ли их клиент скачать еще что-нибудь. Причем в это же время толпа новых посетителей может обнаружить, что ваш сайт не отвечает, так как достигнуто максимальное число разрешенных «апачей»… Наиболее практичным значением параметра keepalivetimeout является что-то между десятью и двадцатью секундами.

Как известно, долгое использование какой-то программы может привести к «утечкам памяти» или каких-то других ресурсов. Чтобы избежать таких проблем есть два параметра: maxkeepaliverequests и maxrequestsperchild. Первый параметр отвечает за принудительное «убиение» процесса после обработки указанного числа keepalive запросов, а второй — после указанного числа «обычных» запросов. В принципе, на абсолютном большинстве систем утечек памяти быть не должно и эти параметры можно сделать достаточно большими — по несколько тысяч. Но на всякий случай последите за поведением сервера — не исключено, что «утечки» обнаружатся в какой-то из библиотек, которые вы используете. Удобнее всего двигаться «снизу вверх» — сначала установить значения небольшими, скажем, 100 и 50, а потом их увеличивать, наблюдая за поведением сервера.

Как увеличить производительность сервера на ОС CentOS. Часть третья: Быстрая оптимизация настроек веб сервера.

В данной статье мы расскажем, как увеличить производительность сервера (выделенного или виртуального) на примере ОС CentOS с помощью быстрой оптимизации настроек веб сервера Nginx и Apache (httpd).

Материал ориентирован на пользователей с небольшим багажом знаний в области администрирования, мы рассмотрим самые простые, и в тоже время действенные, способы повышения производительности сервера. В этой статье мы не станем рассказывать о предназначении и описывать все его настройки, затронем лишь самые необходимые моменты. Статья актуальна для любой панели управления, поэтому разделения на панели делать не будем.

Оптимально работать с сервером по SSH, но если Вы испытываете сложности в работе с SSH - можете открывать файлы через менеджер файлов панели управления. (Инструкция по работе с SSH в первой части этой статьи)

Оптимизация настроек веб сервера Apache (httpd).

Конфигурационный файл веб сервера Apache находится по следующему пути:

/etc/httpd/conf/httpd.conf

В этом файле обязательно нужно настроить ограничения по количеству одновременно запущенных процессов веб сервера. Для этого найдите в нем строку MaxClients , блок должен выглядеть примерно так:

StartServers 5
MinSpareServers 5
MaxSpareServers 20
MaxClients 256
MaxRequestsPerChild 0

Maxclients необходимо высчитать, опираясь на количество оперативной памяти, установленной на Вашем сервере. Также следует учесть количество памяти, используемой одним процессом веб сервера. Узнать количество потребляемой памяти одним процессом веб сервера можете с помощью утилиты top , инструкция по использованию в нашей базе знаний.

Далее отсчитайте 2\3 от общего количества оперативной памяти Вашего сервера и разделите на количество памяти, потребляемой одним процессом веб сервера. Полученное число и будет оптимальное значение MaxClients.

Например, имеем сервер с 8 Гб оперативной памяти. 2\3 от 8 будет 5.3 Гб. Один процесс веб сервера обычно потребляет около 40 Мб памяти. Считаем 5300мб \ 40мб, получаем 132. Лучше округлять в меньшую сторону. Оставляем значение 130, в итоге блок конфигурационного файла должен иметь такой вид:

StartServers 5
MinSpareServers 5
MaxSpareServers 20
MaxClients 130
MaxRequestsPerChild 0

Также включите KeepAlive, для этого найдите в конфигурационном файле строку:

KeepAlive Off

Измените Off на On:

KeepAlive On

После внесения изменений перезагрузите веб сервер командой:

/etc/init.d/httpd restart

Service httpd restart

Оптимизация настроек веб сервера Nginx.

Конфигурационный файл веб сервера Nginx находится по следующему пути:

/etc/nginx/nginx.conf

В нем необходимо настроить количество процессов Nginx. Обычно данная настройка зависит от количества ядер процессора, которые доступны для Вашего сервера. За это отвечает директива worker_processes, в конфигурационном файле это выглядит так:

User apache;

pid /var/run/nginx.pid;
worker_processes 4;

Как видите, количество процессов Nginx настроено для 4х ядер процессора. Если Ваш сервер обрабатывает очень много соединений, можете увеличить это значение на половину, если установить большее значение - это будет в убыток производительности.

Worker_rlimit_nofile 65536;
events {
use epoll;
worker_connections 65536;
}

Это увеличит ограничения для Nginx по количеству обрабатываемых файлов и улучшит его работу. Если в Вашем конфигурационном файле уже прописаны worker_rlimit_nofile или worker_connections - удалите их, оставьте только блок, как на образце.

В итоге начало конф-го файла должно выглядеть таким образом:

User apache;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_processes 4;
worker_rlimit_nofile 80000;
events {
use epoll;
worker_connections 65536;
}
http {

default_type application/octet-stream;
log_format main "$remote_addr - $remote_user [$time_local] "$request" "
"$status $body_bytes_sent "$http_referer" "
""$http_user_agent" "$http_x_forwarded_for"";
access_log /var/log/nginx/access.log main;

Access_log off;

(Просмотреть нагрузку на диск можете с помощью утилиты top)

Также Вы можете включить в Nginx Gzip сжатие. Это может ускорить загрузку Вашего сайта, а также это выгодно в seo продвижении, однако рекомендуем проверить скорость загрузки после включения Gzip, т.к. на сайты с большим количеством запросов это может повлиять негативно. Чтобы включить Gzip сжатие в Nginx , нужно добавить в секцию http { такой код:

Gzip on;
gzip_comp_level 5;
gzip_min_length 10240;


gzip_disable "msie6";

Добавьте этот код на следующей строке после http { Чтобы это выглядело так:

Use epoll;
worker_connections 65536;
}
http {
gzip on;
gzip_comp_level 5;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
gzip_disable "msie6";
include /etc/nginx/mime.types;
default_type application/octet-stream;

Если ниже в коде встречаются настройки Gzip - удалите их.

После завершения настройки, выполните перезагрузку Nginx командой:

/etc/init.d/nginx restart

Service nginx restart

С предыдущими материалами по оптимизации настроек сервера можете ознакомиться по ссылкам:

Если у Вас возникнут трудности в настройке и администрировании сервера - всегда можете обратиться в нашу службу технической поддержки.

Вообще, если вы можете не поднимать Apache , не делайте этого. Задумайтесь, может ли нужные вам задачи выполнять lighttpd или thttpd . Эти веб-серверы могут оказаться весьма кстати в ситуациях, где системных ресурсов на всех не хватает, а работать должно. Ещё раз повторюсь: речь идёт о тех ситуациях, когда функциональности этих продуктов будет достаточно для выполнения поставленных задач (кстати, lighttpd умеет работать с PHP ). В тех ситуациях, где без Apache ну просто никак не обойтись, всё равно обычно можно освободить немало системных ресурсов, перенаправив запросы к статическому контенту (JavaScript, графика) от Apache к легковесному HTTP-серверу. Наибольшей проблемой Apache является его большой аппетит к оперативной памяти. В этой статье я рассмотрю методы, помогающие ускорить работу и снизить объёмы занимаемой им памяти:

  • обработке меньшего числа параллельных запросов;
  • циркуляция процессов;
  • использование не слишком «долгих» KeepAlive;
  • уменьшение таймаута;
  • уменьшение интенсивности логирования;
  • отключение разрешения имён хостов;
  • отключение использования .htaccess .
  • Загрузка меньшего количества модулей

    Первым делом необходимо избавиться загрузки от ненужных модулей. Просмотрите конфиг-файлы и определите, какие модули у вас загружаются. Все ли загружаемые модули вам нужны? Найдите то, что не используется и отключите нафиг, этим вы сэкономите какое-то количество памяти.

    Обработка меньшего числа параллельных запросов

    Чем большему количеству процессов Apache разрешено запускаться одновременно, тем больше одновременных запросов он сможет обработать. Увеличивая это число, вы тем самым увеличиваете и объём памяти, отдаваемой под Apache . Воспользовавшись top, можно увидеть, что каждый процесс Apache занимает совсем немножко памяти, поскольку используются разделяемые библиотеки. В Debian 5 с Apache 2 по умолчанию используется такая конфигурация:

    StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxClients 20 MaxRequestsPerChild 0

    Директива StartServers определяет количество процессов сервера, запускаемых изначально, сразу после его старта. Директивы MinSpareServers и MaxSpareServers определяют минимальное и максимальное количество дочерних «запасных» процессов Apache . Такие процессы находятся в состоянии ожидания входящих запросов и не выгружаются, что даёт возможность ускорить реакцию сервера на новые запросы. Директива MaxClients определяет максимальное количество параллельных запросов, одновременно обрабатываемых сервером. Когда количество одновременных соединений превысит это количество, новые соединения будут поставлены в очередь на обработку. Фактически, директива MaxClients и определяет максимально-допустимое число дочерних процессов Apache ,запущенных одновременно. Директива MaxRequestsPerChild определяет количество запросов, которое должен обработать дочерний процесс Apache , прежде чем завершить своё существование. Если значение этой директивы установлено равным нулю, то процесс не будет «истекать».

    Для своего домашнего сервера, с соответствующими нуждами, я исправил конфигурацию на следующую:

    StartServers 1 MinSpareServers 1 MaxSpareServers 1 MaxClients 5 MaxRequestsPerChild 300

    Конечно же, приведённая выше конфигурация совершенно не годится для использования на высокозагруженных серверах, но для дома, на мой взгляд — самое оно.

    Циркуляция процессов

    Как можно было заметить, я изменил значение директивы MaxRequestsPerChild . Ограничив таким образом время жизни дочерних процессов количеством обработанных запросов, можно избежать случайных утечек памяти, вызванных криво-написанными скриптами.

    Использование не слишком «долгих» KeepAlive

    KeepAlive — это метод поддержки постоянного соединения между клиентом и сервером. Изначально протокол HTTP разрабатывался как не ориентированный на постоянные соединения. То есть, когда веб-страница отправляется клиенту, все её части (картинки, фреймы, JavaScript) передаются с использованием различных, отдельно устанавливаемых соединений. С появлением KeepAlive , у браузеров появилась возможность запрашивать постоянное соединение и, установив его, загружать данные, используя одно установленное соединение. Такой способ даёт неслабый прирост производительности. Однако Apache по умолчанию использует слишком большой таймаут перед закрытием соединения, равный 15-ти секундам. Это значит, что после того, как был отдан весь контент клиенту, запросившему KeepAlive , дочерний процесс ещё 15 секунд будет находиться в ожидании входящих запросов. Многовато, однако. Лучше уменьшить этот таймаут до 2-3 секунд.

    KeepAliveTimeout 2

    Уменьшение таймаута

    Как вариант, можно уменьшить значение директивы TimeOut , которая определяет время ожидания завершения отдельных запросов. По умолчанию её значение равно 300 , быть может, в вашем случае будет иметь смысл это значение уменьшить/увеличить. Я лично пока оставил как есть.

    Уменьшение интенсивности логирования

    На пути к увеличению производительности сервера можно попробовать снизить интенсивность ведения протоколов. Модули, такие как mod_rewrite , могут писать в лог отладочную информацию, и если она вам не нужна — отключайте её вывод.

    Отключение разрешения имён хостов

    На мой взгляд, нет никакой необходимости в том, чтобы выполнять обратное преобразование IP-адресов в имена хостов. Если они уж так сильно вам необходимы при анализе логов, то можно определять их на стадии анализа, а не в процессе работы сервера. За разрешение имён хостов отвечает директива HostnameLookups , которая, вообще-то, по умолчанию и установлена в Off , однако проверьте это, если действительно считаете необходимым отключить преобразование.

    HostnameLookups Off

    Отключение использования.htaccess

    Обработка файлов .htaccess выполняется Apache каждый раз при запросе данных. Мало того, что Apache должен загрузить этот файл, так ещё немало времени и ресурсов уходит на его обработку. Взгляните на ваш веб-сервер и пересмотрите необходимость в использовании файлов .htaccess . Если вам нужны различные настройки для разных каталогов, может быть реально будет их вынести в основной файл конфигурации сервера? А отключить обработку .htaccess можно директивой в конфигурации сервера.

    Похожие публикации