Продолжая тему переезда на выделенный сервер.
Т.к. у меня имелось некоторое количество свободного времени, было решено переделать все «с нуля».
В качестве ОС решил установить Ubuntu server 14.04, т.к. предполагается в дальнейшем установка BigBlueButton, а на Debian-е, в связи с особенностями дистрибутива, установка прерывается на этапе установки ruby gems.
Установка Ubuntu server — процесс несложный. Единственное замечание — если хотите устанавливать с флешки — не пишите её с помощью LiLi. Пишите Unetbootin или UltraISO, и вы сэкономите себе полчаса времени.
После установки системы ставим нужные нам компоненты:
apt-get install mc htop atop apache2 libapache2-mod-php5 nginx php5-gd php5-cgi php5-cli fail2ban
Дальше в принципе можно настраивать по предыдущей статье. Но есть ньюансы!
Об особенностях переезда — под катом. »
В Ubuntu server 14.04 по умолчанию установлен Apache 2.4.7, в отличие от 2.2 в Debian. То есть просто копированием старых конфигов нам не обойтись.
Первое, самое неожиданное: апач теперь понимает конфиги сайтов в sites-available только если у них расширение .conf.
Лечится либо переименованием конфигов
mv /etc/apache2/sites-available/sigillite.net /etc/apache2/sites-available/sigillite.net.conf
либо изменением глобальных опций в apache2.conf:
Было: IncludeOptional sites-enabled/*.conf Стало: IncludeOptional sites-enabled/*
Второе — настройки безопасности каталогов. Вместо конструкции
Order deny,allow Deny from all
теперь исползуется конструкция вида
Require all denied
Третье — изменение механизма работы mod_rpaf, но об этом позже.
Полный список изменений в работе апача 2.4 можно найти здесь.
Итак, индеец поднят, система настроена «как было». Время заняться оптимизацией.
Шаг 1. Мелкие оптимизации.
Оптимизируем расход памяти индейцем:
mcedit /etc/apache2/mods-available/mpm_prefork.conf
<IfModule mpm_prefork_module> StartServers 2 MinSpareServers 5 MaxSpareServers 10 MaxRequestWorkers 50 MaxConnectionsPerChild 200 ServerLimit 50 </IfModule>
В данном случае у нас используется модуль prefork. Он запускает отдельный процесс под каждое соединение, что не есть хорошо, но пока оставим так.
Закроем apache из мира и разнесем виртуальные хосты по портам.
Apache в нашем случае является back-end-ом nginx-а, соответственно, обращается к нему исключительно nginx. Это значит, что апачу не нужно слушать порты на всех интерфейсах, а достаточно слушать только на локальном.
Кроме того, можно разнести наши виртуальные хосты по разным портам. Это облегчит диагностику в дальнейшем, и немного изолирует сайты друг от друга.
mcedit /etc/apache2/ports.conf
Listen 127.0.0.1:8090 #порт для нашего сайта Listen 127.0.0.1:8092 #порт для crm #Listen 127.0.0.1:8094 #Listen 127.0.0.1:8096 #Listen 127.0.0.1:8098
В файле /etc/apache2/sites-available/sigillite.net.conf заменим
<VirtualHost *:8090>
на
<VirtualHost 127.0.0.1:8090>
И соответственно в /etc/nginx/sites-available/sigillite.net установим параметр proxy_pass в значение
proxy_pass http://127.0.0.1:8090/;
Перезапускаем apache и nginx.
Все, теперь nginx и apache общаются через локальный интерфейс.
Настроим передачу адреса пользователя из nginx в apache.
Если сейчас заглянуть в логи apache, мы увидим примерно следующее:
%127.0.0.1 - - [24/Feb/2015:23:51:22 +0200] "GET / HTTP/1.0" 200 22068 "http://sigillite.net/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"
Т.е. вместо IP клиента мы получаем IP nginx-а. Исправить эту ситуацию ранее помогал модуль mod_rpaf.
Попробуем настроить:
В /etc/nginx/sites-available/sigillite.net в секции перенаправления на apache (после proxy_pass) пропишем:
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
В /etc/apache2/mods-available/rpaf.conf:
#<IfModule rpaf_module> <IfModule mod_rpaf-2.0.c> #для корректной работы в apache 2.4.7, не вникал RPAFenable On RPAFsethostname On RPAFproxy_ips 127.0.0.1 your_real_ip RPAFheader X-Real-IP RPAFheader X-Forwarded-For </IfModule>
a2enmod rpaf
Перезапустим apache и nginx.
Все, теперь у нас в логах отображается IP клиента.
Для apache 2.2 этого достаточно, но 2.4.7 почему-то продолжает подсовывать 127.0.0.1 в REMOTE_ADDR:
В принципе, можно оставить и так, если данная переменная нигде не используется. У меня из нее берутся данные для модуля учета заходивших в гости ботов, поэтому я исправлю.
Чтобы пофиксить это, в 2.4.7 нужно загрузить еще 1 модуль:
a2enmod remoteip
и добавить в apache2.conf:
RemoteIPHeader X-Real-IP
Теперь после перезапуска Apache REMOTE_ADDR отображается правилно
Шаг 2. Кеширование.
В рамках оптимизации работы блога решил проверить производительность.
Для этого в файл footer.php темы вордпресс достаточно добавить следующий код:
<?php echo "Статистика:" . get_num_queries() . "/ "; timer_stop(1); echo "s/ ". round(memory_get_usage()/1024/1024, 2) . " MB "; ?>
теперь в правом нижнем углу футера будет отображаться вот такая информация:
Первый параметр — это количество запросов к БД, второй — время загрузки страницы, и третий — использованная для загрузки память.
Постараемся минимизировать эти данные.
Сначала разберемся — куда уходят наши ресурсы.
WordPress — это по сути набор php-скриптов, который при каждом обновлении страницы извлекает данные из БД, формирует на основании них страницу и отображает ее.
Т.к. РНР — интерпретируемый язык, то он «компилирует» код при каждом его выполнении. Этот процесс занимает время и ресурсы нашего компьютера.
Также при каждом обновлении страницы WordPress извлекает данные для отображения из БД. Т.е. при каждом обновлении страницы у нас:
- создается форк процесса apache
- компилируются и выполняются php-скрипты
- с помощью выполняющегося php-скрипта запрашиваются данные из БД
Т.о. для уменьшения нагрузки нам необходимо:
- минимизировать количество запросов к БД
- минимизироват количество компиляций php-скриптов
- оптимизировать работу apache
Кеширование php с помощью ZendOpCache
Первым этапом мы кешируем php. Т.е. сделаем так, чтобы скрипт компилировался не при каждом обращении к нему, а только при первом, а далее выполнялся из кеша.
Для этого установим Zend OpCache:
apt-get install php-pear apt-get install build-essential php5-dev pecl install zendopcache-7.0.3
Настроим его согласно рекомендаций самих разработчиков:
mcedit /etc/php5/mods-available/opcache.ini
zend_extension=opcache.so opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=60 opcache.fast_shutdown=1 opcache.enable_cli=1
Перезапускаем апач и смотрим:
Имеем около 60% экономии памяти на каждом обновлении страницы.
Можно также установить OpCache Control Panel, прописать ее на виртуалхост или добавить в папку с вордпресс и наблюдать за состоянием кеша прямо в браузере
Кеширование запросов в БД
Второй этап — кеширование запросов в БД. В этом нам поможет плагин для WordPress db-cache-reloaded-fix.
Все просто — установили, активировали, смотрим:
Количество запросов в БД уменьшилось на 90%.
Тут ест ньюанс — если имеется динамически обновляющийся контент, либо что-то что не нужно кешировать (например, есть форма входа, и нам совсем не нужно чтобы учетные данные первого вошедшего кешировались) — придется либо танцевать с бубном дабы исключить ее данные из кеша, либо включать wrapper mode, тогда прирост производительности процентов 10.
Оптимизация работы apache
По умолчанию apache работает в режиме prefork. Это означает, что apache при запуске создает какое-то количество процессов, от которых на каждое соединение создается форк.
Параметры количества создаваемых форков определяется в файле /etc/apache2/mods-available/mpm_prefork.conf
Оптимальные параметры выбираются во многом эмпирически, методом проб. Пример настройки, оптималной для меня, указан выше.
Если данные параметры не устраивают — можно попробовать сконфигурировать apache под использование модуля mpm_worker. В отличии от префорка, воркер не плодит процессы, а открывает потоки в рамках определенного в конфиге количества процессов.
Я решил пропустить этот этап и попытаться выбросить apache из конфигурации вообще, переложив роль back-end на плечи модуля php-fpm. Об этом подробнее — в следующей статье.
Отмечу, что сам я использую не все функции, которые описаны в данной статье.
Например, меня не устроила работа bd-cache-reloaded, поскольку я использую форму входа (данные из которой он также успешно кеширует). Однако, для многих данный плагин будет полезен, поэтому я счел нужным включить его в данную статью.
А в следующем посте мы попробуем выбросить из нашей конфигурации самое святое — апач )