Пользователь
0,0
рейтинг
10 ноября 2011 в 05:17

Администрирование → LAMP +Nginx на VPS стабильно и без лишней головной боли из песочницы

Задача — на минимальных ресурсах VPS развернуть хостинг нескольких не нагруженных сайтов. Сделать это быстро и удобно с минимальными проблемами в будущем и не падать на пиковых нагрузках.

Основные принципы:

1. ОС — Centos-6 86_x64 потому что стабильно, удобно и легко обновляемо.
2. Никакого самосборного софта. А то как говорится «командой make && make install любой дистрибутив превращается в Slackware.»

Маленькое уточнение, на данный момент я использую тарифный план v256 у хостинг провайдера flynet.pro (256Мб оперативки) и не рассчитываю на большую нагрузку так что большая часть относится именно к такому количеству оперативной памяти, но в целом решения легко переносимы фактически на все тарифные планы разных хостинг-провайдеров.
И еще одно уточнение — хостинг делается «для себя». Тут недостаточно описаны моменты, которые стоит учитывать, если вы даете доступ к администрированию сайтов посторонним людям.

Поехали.
1. Проверяем обновления.
Установочный образ у хостинг провайдера может оказаться не особо свежим.
[root@test ~]# yum update

Есть что обновлять — обновляем. Нет — радуемся.

2. Подключаем репозитарий EPEL (http://fedoraproject.org/wiki/EPEL) из которого будем ставить недостающий софт.
[root@test ~]# rpm -ihv download.fedora.redhat.com/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm


3. Ставим нужный нам софт
[root@test ~]# yum install httpd mysql-server php vsftpd mc phpMyAdmin php-eaccelerator sysstat crontabs tmpwatch


Кратко о софте:
httpd — Apache штатная версия для Centos-6 — 2.2.15
mysql-server — Mysql 5.1.52
php — PHP 5.3.2
vsftpd — довольно удобный FTP сервер vsftpd 2.2.2
mc — некоторые вещи все-таки удобнее делать в mc чем в командной строке.
phpMyAdmin — аналогично с mc. управлять mysql базами в phpMyAdmin всетаки удобнее.
php-eaccelerator — акселератор для PHP. Заметно увеличивает скорость выполнения скриптов и снижает нагрузку на процессор. Да и на память.
sysstat — на случай если нам захочется посмотреть как поживает система.
crontabs — для выполнения заданий по расписанию.
tmpwatch — утилита для удаления устаревших файлов.

На самом деле установится несколько больше пакетов, к тем пакетам что мы попросили установить добавится все необходимое для их функционирования.
В результате получается:
Install 44 Package(s)
Upgrade 0 Package(s)

Total download size: 37 M
Installed size: 118 M


4. Командой free смотрим, есть ли у нас своп и если нет, то создаем его и подключаем. Если есть – радуемся и пропускаем этот пункт.
Тут важный момент — активное использование свопа — очень плохо. Если идет активный свопинг — значит нужно что-то оптимизировать или урезать. Если оптимизировать и урезать не получается — придется переходить на более дорогой тарифный план. Еще стоит учитывать что хостинг-провайдер может обидиться на слишком активное использование свопа.
Но совсем без свопа тоже не очень хорошо — oom killer — штука страшная. Может ненароком убить mysqld и вместо того чтобы просто тормозить ваши сайты будут совсем лежать.
Замечание — делать своп больше имеющейся оперативной памяти не нужно. Пользы от него не будет, а место он скушает.

Создаем своп следующим образом:
[root@test /]# dd if=/dev/zero of=/swap bs=1M count=256
[root@test /]# mkswap /swap


подключаем
[root@test /]# swapon /swap

ну и для того чтобы оно подключалось автоматически записываем эту команду в /etc/rc.local
Проверить наличие и занятость свопа можно командами top или free

5. Включаем и запускаем демонов
[root@test /]# chkconfig httpd on
[root@test /]# chkconfig mysqld on
[root@test /]# chkconfig crond on

[root@test /]# service httpd restart
[root@test /]# service mysqld restart
[root@test /]# service crond restart


6. Создаем пользователей для сайтов. Я предпочитаю чтобы имя пользователя было аналогично домену сайта.
[root@test /]# adduser testsite.ru
[root@test /]# adduser mysite.ru
[root@test /]# adduser cfg.testsite.ru

Далее создаем дополнительные в каталогах пользователей. html (в котором будет основное содержимое сайтов) и log в которую будут писаться логи для этого сайта и выставляем права. Права ставим: пользователю – полный доступ, группе apache чтение и листинг директорий, остальным – фикус.
Права можно выставить и руками, а можно и воспользоваться небольшим скриптиком:
cd /home
for dir in `ls -1 `; do
mkdir /home/$dir/log
mkdir /home/$dir/html
chown -R $dir:apache $dir
chmod ug+rX $dir
done;


7. Настраиваем веб сервер. Правим /etc/httpd/conf/httpd.conf
Из действительно нуждающегося в изменении — настраиваем модуль prefork так чтобы он изначально кушал поменьше памяти и ограничивал свои аппетиты.
Дело в том что Apache изначально настроен на запуск до 256 своих рабочих процессов, при том что один рабочий процесс запросто занимает 20-40Мб (256*20=5Гб) это запросто может привести к проблемам, особенно на скромных VPS где есть всего 256Мб оперативки.
Поэтому мы ограничиваем их количество разумными цифрами изсходя из доступной нам оперативной памяти. Например 5 процессов апача при среднем размере 30Мб займут около 150Мб — что уже терпимо.
Было:
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000


Стало:
<IfModule prefork.c>
StartServers 2
MinSpareServers 2
MaxSpareServers 3
ServerLimit 5
MaxClients 5
MaxRequestsPerChild 1000


Такая настройка не даст апачу расплодиться сверх меры и скушать всю оперативку. В зависимости от реальной нагрузки параметры, возможно, стоит пересмотреть.
Ну и раскомментируем строку
NameVirtualHost *:80

Для того чтобы на одном ip адресе иметь много сайтов.

Далее переходим в директорию /etc/httpd/conf.d/ и настраиваем наши сайты.
Там можно удалить welcome.conf который выключает индексы и выдает вместо нее страничку «Apache 2 Test Page».
Следует учесть, что конфиги виртуальных хостов в этой директории применяются по очереди в алфавитном порядке.
Для того чтобы пользователь зайдя по IP адресу на какой либо из наших сайтов не попал на совершенно другой (который будет первым по списку) в директорию conf.d стоит положить файл с именем например 000-default.conf и таким содержимым:
<VirtualHost *:80>
ServerName localhost.local
DocumentRoot "/var/www/html"


и положить в директорию /var/www/html/ файлик index.html с пожеланиями.

Далее для каждого из наших виртуальных хостов создаем конфиг файл по примерно такому шаблону:
<VirtualHost *:80>

ServerName testsite.ru
ServerAlias www.testsite.ru
ServerAdmin webmaster@testsite.ru
ErrorLog /home/testsite.ru/log/error.log
CustomLog /home/testsite.ru/log/access.log combined
DocumentRoot /home/testsite.ru/html/

<Directory "/home/testsite.ru/html">
Order allow,deny
Allow from all




В эти же файлы, по вкусу можно добавить индивидуальные настройки каких либо модулей.

Перезапускаем apache и смотрим все ли работает.
[root@test /]# service httpd restart


apache должен запуститься нормально. В директориях log сайтов должно создаться по 2 файла логов.
При обращении к серверу по IP адресу должен выводиться файл который вы положили в /var/www/html/, а при обращениях по именам сайтов вы должны видеть содержимое директории html (пустое скорее всего) и записи в файле access.log соответствующего сайта.

8. Настраиваем mysql. Первым делом удаляем базу test и задаем пароль пользователя root на mysql
[root@test /]# mysql


mysql> DROP DATABASE test;
mysql> USE mysql;
mysql> UPDATE user SET Password=PASSWORD('MyMysqlPassword') WHERE user='root';
mysql> FLUSH PRIVILEGES;
mysql> quit


С MySql проблема примерно такая же как с Apache — требовательность к оперативной памяти которая на VPS весьма дорога.
Для уменьшения объема используемой памяти sql сервером правим /etc/my.cnf следующим образом:
в секцию [mysqld] добавляем следующее:
key_buffer = 16M
max_allowed_packet = 10M
table_cache = 400
sort_buffer_size = 1M
read_buffer_size = 4M
read_rnd_buffer_size = 2M
net_buffer_length = 20K
thread_stack = 640K
tmp_table_size = 10M
query_cache_limit = 1M
query_cache_size = 32M
skip-locking
skip-innodb
skip-networking


и в конец файла добавляем эти строки:
[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[isamchk]
key_buffer = 8M
sort_buffer_size = 8M

[myisamchk]
key_buffer = 8M
sort_buffer_size = 8M

[mysqlhotcopy]
interactive-timeout


перезапускаем mysqld чтобы убедиться что все нормально:
[root@test ]# service mysqld restart


Так же нужно заменить что опция «skip-networking» делает возможным обращение к серверу только с локальной машины через сокет. Если требуется сетевой доступ — эту опцию включать не нужно.
Такие настройки позволят минимизировать память используемую процессом mysql и нормально работать на незагруженном сайте. Но конечно же нужно смотреть на статистику работы mysql и в зависимости от потребностей увеличивать данные здесь лимиты.

Дальнейшее администрирование mysql удобнее производить через phpMyAdmin.
Теперь один нюанс — по умолчанию phpMyAdmin доступен по пути /phpMyAdmin на всех наших сайтах.
Чтобы этого не было создаем специализированный сайт для управления (например cfg.testsite.ru) и настраиваем его аналогично остальным.
Потом переносим все содержимое файла /etc/httpd/conf.d/phpMyAdmin.conf в конфиг этого сайта, а сам файл phpMyAdmin.conf удаляем или переносим куда-нибудь из дириктории conf.d.
После таких действий phpMyAdmin будет доступен по пути /phpMyAdmin/ только на специально выделенном сайте.
Ну и для того чтобы в него можно было войти в файле конфигурации сайта меняем
<Directory /usr/share/phpMyAdmin/>
Order Deny,Allow
Deny from All
Allow from 127.0.0.1
Allow from ::1


<Directory /usr/share/phpMyAdmin/setup/>
Order Deny,Allow
Deny from All
Allow from 127.0.0.1
Allow from ::1


на
<Directory /usr/share/phpMyAdmin/>
Order Deny,Allow
Deny from All
Allow from 127.0.0.1
Allow from ваш.ип.адрес.
Allow from ::1


<Directory /usr/share/phpMyAdmin/setup/>
Order Deny,Allow
Deny from All
Allow from 127.0.0.1
Allow from ваш.ип.адрес.
Allow from ::1


После этого phpMyAdmin будет доступен с вашего ip адреса.

Авторизуемся в нем как пользователь root с тем паролем что установили.
Чтобы создать пользователя идем в «Привелегии» — «Добавить нового пользователя»
имя пользователя — произвольное, я предпочитаю использовать имя сайта чтобы уменьшить путаницу.
Хост — локальный (мы же делаем его для сайта который будет крутиться тут же?)
Пароль — генерировать. (не забываем копировать пароль)
Ставим галочку — «Создать базу данных с именем пользователя в названии и предоставить на нее полные привилегии»
Применяем.
В итоге получаем пользователя с выбранными вами именем, паролем и базой данных с аналогичным названием.

9. Часто заливать файлы на хостинг удобнее через фтп. для этого мы и установили vsftpd
редактируем его конфиг /etc/vsftpd/vsftpd.conf
выключаем анонимный логин, меняем
anonymous_enable=YES

на
anonymous_enable=NO


и раскоментируем
chroot_local_user=YES


Теперь чтобы можно было зайти на фтп определенного сайта соответствующему пользователю нужно задать пароль
[root@test /]# passwd testsite.ru


И не забываем что по умолчанию этот пользователь с установленным паролем может зайти по SSH. Чтобы отключить эту возможность проще всего сменить шелл пользователя
[root@test etc]# chsh -s /sbin/nologin testsite.ru


Включаем и запускаем vsftpd
[root@test /]# chkconfig vsftpd on
[root@test /]# service vsftpd start


Проверяем, все ли работает.

Ну и на последок совсем простенький «оперативный бекап». По принципу «бекапов много не бывает».
Лучше бы использовать что-то более правильное, но плохой бекап все-таки лучше полного отсутствия.
Такой бекап может служить неплохим дополнением полному бекапу виртуальной машины у хостинг-провайдера. Но, ни в коем случае не его заменой.
Бекапим содержимое сайтов и баз данных, а так же настройки в каталоге /etc/.
Создаем директорию /backup/ и ставим на нее права «700»

[root@test /]# mkdir /backup/
[root@test /]# chmod 700 /backup/


В директории /etc/cron.daily/ создаем файл backup.sh и так же ставим на него права «700».
[root@test /]# touch /etc/cron.daily/backup.sh
[root@test /]# chmod 700 /etc/cron.daily/backup.sh


Файл имеет следующее содержание:

#!/bin/sh

#Бекапим все директории html наших сайтов
tar -cf - /home/*/html/ | gzip > /backup/sites-`date +%Y-%m-%d`.tar.gz

#Бекапим все базы даных в один файл
mysqldump -u root --password=MyMysqlPassword --all-databases | gzip > /backup/mysql-`date +%Y-%m-%d`.dump.gz

#Бекапим конфигурационные файлы
tar -cf - /etc/ | gzip > /backup/etc-`date +%Y-%m-%d`.tar.gz

#Удаляем файлы бекапов старше 7 дней
tmpwatch -t -m 7d /backup/


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

#!/bin/sh
for dir in `ls -1 /home/ `; do
tar -cf - /home/$dir/html/ | gzip > /backup/sites-$dir-`date +%Y-%m-%d`.tar.gz
mysqldump -u root --password=MyMysqlPassword $dir | gzip > /backup/mysql-$dir-`date +%Y-%m-%d`.dump.gz
done;

#Бекапим конфигурационные файлы
tar -cf - /etc/ | gzip > /backup/etc-`date +%Y-%m-%d`.tar.gz

#Удаляем файлы бекапов старше 7 дней
tmpwatch -t -m 7d /backup/


10. Обновления.
Не забываем время от времени обновлять систему.
[root@test ~]# yum update

Благодаря политике RHEL/Centos в отношении к софту версии софта после обновления останутся теми же и нечаяно положить сервер из-за того что в конфиге что-то поменялось шансов очень мало.
Правда в этом подходе есть и минус — через три года в Centos-6 будут теже версии софта что и сейчас. Но если наша цель стабильность — это нам подходит.

11. Тестирование.
Очень рекомендую провести после настройки тестирование сайта.
Первый пункт тестирования — перезагрузка сервера и проверка того что все нужные демоны стартанули и все работает как ожидалось. Я бы вообще порекомендовал не гнаться за циферками аптайма а перезагружаться после установки или изменения версий любого серверного софта стартующего автоматом.
Лучше узнать, что Apache не стартует в автозапуске после собственноручного планового ребута, чем узнать, что у хостера были проблемы и в следствии ребута вашей виртуалки сайты на ней уже полдня как не работают.
Далее — нагрузочное тестирование при помощи утилиты ab (Apache HTTP server benchmarking tool).
В данном тестировании нас интересует не столько количество попугаев сколько поведение сервера под нагрузкой. На нем не должно быть умирающих процессов и активного свопинга.
Для тестирования нам потребуется сайт размещенный на этом сервере в рабочем состоянии. И «типичная» страница с этого сайта. Ну или можно использовать не типичную, а наиболее тяжелую.

Я для примера провожу тестирование на свежеустановленном Drupal 7.9

Из всего многообразия командной строки ab нам потребуются всего 2 параметра -n — количество http запросов -c — количество одновременных запросов (потоков).
Во время выполнения теста во второй ssh сессии с помощью top наблюдаем за тем как поживает сервер.

100 запросов в 2 потока.

[root@test ~]# ab -n 100 -c 2 testsite.ru


Из вывода ab мне особо интересны «Requests per second», «Time per request» и «Failed requests» которые дают общее представление о производительности сервера.

Failed requests: 0
Requests per second: 6.20 [#/sec] (mean)
Time per request: 322.788 [ms] (mean)


Видно, что сервер обрабатывает 6 с копейками запросов в секунду и тратит 322 миллисекунды на генерацию одной страницы.

Из вывода top интересно распределение памяти и загрузка процессора.

Tasks: 62 total, 3 running, 59 sleeping, 0 stopped, 0 zombie
Cpu(s): 19.9%us, 5.3%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.4%si, 74.5%st
Mem: 244856k total, 151624k used, 93232k free, 3752k buffers
Swap: 262136k total, 0k used, 262136k free, 76604k cached


Swap: 0k used — ооочень хорошо.
93232k free + 76604k cached — фактически 170 мегабайт свободной памяти.

100 запросов 5 потоков.

[root@test ~]# ab -n 100 -c 5 testsite.ru


Failed requests: 0
Requests per second: 6.21 [#/sec] (mean)
Time per request: 804.513 [ms] (mean)

Tasks: 63 total, 5 running, 58 sleeping, 0 stopped, 0 zombie
Cpu(s): 17.5%us, 6.2%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 76.3%st
Mem: 244856k total, 159756k used, 85100k free, 3812k buffers
Swap: 262136k total, 0k used, 262136k free, 76660k cached


Количество запросов в секунду осталось тем же а вот время генерации выросло больше чем в 2 раза — уперлись в процессор.

Ну и наконец, хабраэффект или что-то близкое :-)

[root@test ~]# ab -n 500 -c 50 testsite.ru


Failed requests: 0
Requests per second: 6.45 [#/sec] (mean)
Time per request: 7749.972 [ms] (mean)

Tasks: 63 total, 6 running, 57 sleeping, 0 stopped, 0 zombie
Cpu(s): 19.1%us, 5.3%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 75.6%st
Mem: 244856k total, 162740k used, 82116k free, 3884k buffers
Swap: 262136k total, 0k used, 262136k free, 76672k cached


Опять-таки количество запросов в секунду относительно стабильно, а вот время генерации стало уже совсем грустным. Но в тоже время Failed requests — нулевое. Что значит что хоть и медленно, но все работает.
Ну и по поводу памяти — на данный момент Swap: 0k used, 82116k free, 76672k cached — потребление практически не выросло и в принципе можно увеличить некоторые лимиты, но учитывая отсутствие у меня наполнения сайта на данный момент, думаю, этого делать не стоит. А вот позже стоит прогнать тесты на заполненом сайте и в зависимости от результатов уже откорректировать настройки.

12. Установка nginx в качестве фронтенда.

Почему это нужно.
Основная проблема кроется в том как apache обрабатывает входящие соединение. На каждое входящее соединение создается новый процесс или берется один из запущенных и соединение передается ему на обслуживание. До тех пор пока соединение не закрыто этот процесс занимается только им.
В принципе все выглядит хорошо пока у нас много оперативки и/или очень быстрые клиенты (ab запущенный с локалхоста один из таких вариантов), но все становится куда грустнее если клиент сидит на медленном канале или просто никуда не спешит. В таком случае он на время забора реквеста фактически блокирует один из процессов который на это время выключается из работы сервера.
Таким образом в теории имея сервер на 100мбит канале и одного настойчивого клиента на диалапе с регетом мы можем получить нечто-вроде DOS — клиент в несколько потоков заблокирует фактически все наши процессы apache которых у нас в виду малого количества оперативной памяти весьма не много.
Решается данная проблема установкой какого-либо легкого http сервера в виде фронтенда. При наличии фронтенда все входящие соединения принимаются им, затем запрос передается apache и быстро получается ответ тем самым освобождая процесс apache для новых запросов. Фронтенд же не спеша и не растрачивая лишних ресурсов отдает полученный ответ уже запросившему ему клиенту.
Дополнительным бонусом фронтенд может сам отдавать статическое содержимое — например картинки, css и т.п. снимая нагрузку с тяжелого апача.

[root@test ~]# rpm -ihv centos.alt.ru/pub/repository/centos/6/x86_64/centalt-release-6-1.noarch.rpm
[root@test ~]# yum install mod_realip2 nginx-stable


Для того чтобы apache и наши скрипты в запросах видели реальный ip адрес клиента а не адрес фронтенда у нас будет установлен mod_realip2.
редактируем /etc/httpd/conf.d/mod_realip2.conf, раскоментируем
RealIP On
RealIPProxy 127.0.0.1
RealIPHeader X-Real-IP


редактируем httpd.conf и файлы в /etc/httpd/conf.d/
меняем все указания на порт 80 на порт 8080
Всего менять нужно три директивы:
Listen 127.0.0.1:8080
NameVirtualHost *:8080
<VirtualHost *:8080>


редактируем /etc/nginx/nginx.conf
user apache;
worker_processes 2;


Я использую запуск nginx из под пользователя apache поскольку изначально мы давали все права с расчетом именно на него.
Так же не лишним будет закомментировать директиву access_log в nginx.conf чтобы избежать двойного ведения лога.
error_log лучше не трогать — ошибки у апача и nginx все-таки разные.

В секции server правим директиву listen и ставим:
listen 80 default


меняем:
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

на
location / {
proxy_pass 127.0.0.1:8080/;
}


В директории /etc/nginx/conf.d/ создаем файл proxy.conf со следующим содержанием
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;


перезапускаем apache и nginx
service httpd restart
service nginx restart

и проверяем все ли работает.

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

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

Для этого придется в дополнение к виртуальным хостам apache завести виртуальные хосты nginx и указать что раздавать.
Для этого в каталоге /etc/nginx/conf.d/ создаем файл с именем нашего сайта и расширением .conf со следующим содержимым:
server {
listen 80;
server_name testsite.ru www.testsite.ru;
location / {
proxy_pass 127.0.0.1:8080/;
}

location ~ /\.ht {
deny all;
}

location /sites/default/files {
root /home/testsite.ru/html;
access_log /home/testsite.ru/log/access_static.log combined;
}
}


В этом примере для сайта на CMS Drupal статическое содержимое каталога /sites/default/files раздается через nginx, а за всем остальным мы уже идем к апачу.
Еще один варинт — заменить директиву location на:
location ~ \.(jpg|gif|png|css|js|ico)$ {
root /home/testsite.ru/html;
access_log /home/testsite.ru/log/access_static.log combined;
}

В таком случае все файлы с соответствующими расширениями будут отдаваться nginx'ом. Но в данном варианте есть маленький минус — nginx не умеет работать с файлами .htaccess поэтому если у вас там есть какое либо содержимое, закрытое от просмотра .htaccess'ом — от использования такого варианта стоит воздержаться.

Еще стоит заметить, что в данной ситуации мы получаем два лога на один сайт. Отдельно лог запросов, по которым отработал апач и отдельно лог содержимого отданного nginx.
Как вариант — перенести директиву access_log из секции location в секцию server и отключить access_log в виртуальном хосте апача. В таком случае лог будет вести только nginx.
Но для посмотреть «как же это работает» двойной лог может оказаться интересным — по ним сразу видно какая часть нагрузки на кого приходится.

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

UPD: Исправленно несколько опечаток
UPD: Исправлено подключение swap, спасибо AngryAnonymous
UPD: Добавленно описание установки и настройки nginx, спасибо masterbo за пинок в правильную сторону.
Еще вариант бекап скрипта от odmin4eg: habrahabr.ru/blogs/s_admin/132302/#comment_4391784

Жду критики.
Александр Кох @alexk24
карма
16,7
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Администрирование

Комментарии (61)

  • +8
    Вместо Апача стоит поставить Энженикс или Лайти…
    • 0
      Если рассматривать в ключе данной статьи, то по моему мнению ngnix стоит ставить уже на следующем уровне развития проекта, по достижению определенной нагрузки на имеющиеся решение. И ставить в качестве фронтенда, а не на замену апачу. Будет более красивое решение с большей совместимостью. Если же мы сразу ожидаем большую нагрузку, тогда да, действительно стоит применить другой подход. Но ведь нагрузки может и не быть.
      • –3
        Тогда зачем вы поставили php-eaccelerator? :)
        • +3
          php-eaccelerator в данном случае не столько средство снижения нагрузки, а еще и средство увеличения юзабилити.
          На данный момент на VPS принято ограничивать CPU. И на дешевых тарифах при тех же 400-500Mhz разница в скорости генерации странички, например друпалом, с php-eaccelerator и без него весьма ощутимая. Т.е. сайт с акселератором шевелится ощутимо лучше.
          • 0
            У вас, судя по конфигурации, апач работает в prefork режиме. Не слишком-то это эффективно для eaccelerator, мне кажется. Не хотите переключить Apache в worker режим? В CentOS для этого нужно отредактировать файл /etc/sysconfig/httpd и поставить там HTTPD=/usr/sbin/httpd.worker
            • 0
              php.net/manual/en/install.unix.apache2.php
              We do not recommend using a threaded MPM in production with Apache 2. Use the prefork MPM, which is the default MPM with Apache 2.0 and 2.2. For information on why, read the related FAQ entry on using Apache2 with a threaded MPM
              • 0
                Да-да. Только от акселераторов периодически бывает больше глюков, чем от worker-mpm. У меня два сервера на php-fpm с mpm-worker. Нормально работают. Ничего не падает.
      • +8
        Верно говорят, nginx+php-fpm сразу надо осваивать. Скорость, низкое потребление ресурсов, кэши разных уровней, гибкость в настройках. Апач — это страшный сон.
      • +3
        А что, у Nginx есть какие-то недостатки, которые не позволяют его использовать на малопосещаемых сайтах?

        А что, у Nginx есть какие то проблемы с работой без Apache, но с php-fpm? насколько я знаю — наоборот. Хотя бы возможность запуска каждого сайта из под отдельного юзера.
        • +2
          Есть цели и есть инструменты. Одни инструменты лучше подходят под одни цели другие под другие. Тема nginx vs apache — весьма обширна и холиварна. Не спорю что у Nginx есть объективные преимущества, но не стоит забывать и о некоторых недостатках. В рассмотренном мной ключе (не получить дополнительных проблем в последствии) основным недостатком является то что разработчики разного рода CMS и т.п. дают в документации рекомендации именно по работе с апачем. Не стоит так же забывать, что решения «из коробки» опять таки обычно комплектуются под apache.
          Соответственно в данном контексте установка Nginx ведет к повышению производительности (что не является в данном контексте основной целью) и увеличению времени затрачиваемого на поддержку и поиск решений того как портировать какой-либо конфиг с апача на nginx.
          В данном случае ситуация в чем-то сродни скачиванию последних версий софта «make && make install». Да, мы получаем самые свежие версии софта с новыми фитчами, но в последствии берем на себя всю дальнейшую работу по обновлению. Здесь же ставя Nginx мы получаем более быстрый сервер, но получаем дополнительную работу по адаптации конфигов.
          • +4
            Для тех кто не хочет напрягаться есть куча shared-хостингов.

            Если вы не хотите пользоваться Nginx из-за того, что нужно осваивать новое — то я вам сочувствую. Конфиги там гораздо проще чем у Apache, есть даже конвертер из .htaccess www.anilcetin.com/convert-apache-htaccess-to-nginx/

            Выставлять на сервер один Apache НЕЛЬЗЯ. Учить этому новичков тем более.
            Если вы его так обожаете — все равно нужно спереди поставить Nginx.

            Хотя бы вот, почему:
            habrahabr.ru/blogs/infosecurity/127029/
            habrahabr.ru/blogs/infosecurity/127199/
            • –5
              Боюсь это уже перерастает в холивар.
              Я не говорил что не хочу пользоваться Nginx. Так же я не говорил, что я им не умею пользоваться или даже, что я им не пользуюсь. :-)
              Просто я считаю, что для данной задачи nginx — излишество которое потом потребует больше времени на поддержку и адаптацию. Повторяю — именно в рассматриваемом случае. Если мы ждем существенную нагрузку — тогда либо ставим nginx фронтэндом (что довольно легко вписывается в данную концепцию), либо делаем все с нуля на nginx php-fpm. Но это уже будут решения другого уровня.

              На этом я тему обсуждения «почему тут нет nginx» заканчиваю.
              • 0
                Окей. Покажите, пожалуйста, скриншот htop вашей vps.

                Желательно при нагрузке, и без. Мне не верится, что вам хватает 256 памяти, на 64 битной системе с Apache. А спорить да, больше не будем.
                • –3
                  top или htop имеет принципиальную разницу?

                  Если нет — данные тестирования имеются в конце статьи.
                  Если нужны другие данные — с удовольствием их предоставлю, только попрошу описать условия тестирования. Или сами можете развернуть аналогичную систему и протестировать. Все описанное выше делается в течении 30 минут копипастом из статьи в ssh клиент.
                  • 0
                    htop наглядно показывает сколько кушается памяти, сколько лежит в свопе, загрузку проца и основных процессов.

                    А еще там видно uptime.

                    По моему, это очень важно, так как после старта и тестов у меня на виртуалке скушано 150 мб ОЗУ, а через неделю — уже под 350.
                    • 0
                      Справедливости ради стоит заметить, что потребление памяти, как и своппинг, управляются настройками в sysctl.conf, так что расход ОЗУ на системе на большом промежутке времени ни о чём не говорит.
                      У меня лично VPS с 512Мб с lighttpd. Настроено так, что кэш забивает практически полностью всю свободную память (оставил резерв = 32Мб), учитывая то, что редких прожорливых php-скриптов у меня на сайтах нет.

                      p.s. сам подумывал статью написать про настройку голого vps, только не уверен надо ли. Вроде и так всё разжевано везде.
              • 0
                Откуда больше времени на адаптацию? Настроить nginx как reverse proxy это такое непостижимое занятие? Apache использует модель которая годится только для отдачи контента быстрым клиентам — nginx, локальные клиенты, сайт с 8 посещениями в час. Выставлять Apache на улицу с ТАКИМ-ТО объемом памяти имеет смысл только если никто кроме вас не будет им пользоваться.

                > либо делаем все с нуля на nginx php-fpm.

                Если вы используете cms которая не обновлялась уже несколько лет — да это проблема. Все остальное спокойно заводится под php-fpm, и не важно, apache + php-fpm или nginx + php-fpm.
              • 0
                Поправьте меня если я не прав:
                1. Вы считаете, что Apache со своей армией потомков нормально без nginx может обслуживать медленные соединения и это не отразится на занимаемой памяти? Если так, то вы ошибаетесь. Nginx стоит поставить перед apache как минимум для того, чтобы процесс apache быстро отдал ответ nginx-у и освободил память для следующего запроса, а nginx уже разберется с медленным клиентом без затрат дорогого ресурса.

                2. Вы не стали использовать nginx потому, что не нашли в репозиториях, а «make делает любой дистрибутив… и дальше по тексту»? Тогда это просто лень, чреватая проблемами именно в ситуации ограниченных ресурсов VDS
                • 0
                  Хотя ваши предположения не верны(т.е. я так не считаю и я не настолько ленюсь), хочу сказать спасибо — потому что своим первым вопросом натолкнули меня на правильное понимание проблемы.
                  • 0
                    Пожалуйста. А еще задумайтесь над тем, чтобы к своему apache (раз уж вы не собираетесь отходить от .htaccess) привязать один (по числу доступных ядер) постоянно висящий в памяти процесс php-fpm вместо модуля mod_php, который дублируется в памяти с каждым запросом. вы так тоже много сэкономите и по памяти и по производительности.
        • +1
          >Хотя бы возможность запуска каждого сайта из под отдельного юзера.
          Не холивара ради, но: www.suphp.org/Home.html
  • +4
    Про бэкап БД, сделать можно чуть красивее.

    #!/bin/bash
    USER="root"
    PASSWORD="myRootPWD"
    mkdir /var/backup/database/`date +%F`;
    for DB in `mysql -u$USER -p$PASSWORD -N -e 'show databases' | awk '{print $1}'`; do
         mysqldump --user=$USER --host=$HOST --password=$PASSWORD ${DB} | gzip > /var/backup/database/`date +%F`/${DB}.sql.gz;
            echo "${DB} Backup";
        done
    


    Листаем список всех БД, и бэкапим каждую в отдельный файл.
    • +1
      Вы забыли grep -v. Этот скрипт будет ошибками руту в почту сыпать.
    • 0
      mkdir /var/backup/database/`date +%F`;
      В этой строчке после mkdir добавьте -p, потому что если нету в цепочке "/var/backup/database/" одной из директрой, то бэкап создаваться не будет.
  • +3
    Хотелось бы видеть еще пару строк по поводу настройки мыльного сервера, почту-то все же надо принимать/отправлять и почему-то в статьях про lamp все об этом забывают.
    • +1
      Наверное по тому что LAMP это Linux Apache Mysql PHP/Perl.
  • +1
    «php — PHP 5.3.2»

    забываем про дырки в PHP до 5.3.8?
    • +2
      Это Centos. т.е. почти RHEL у которго несколько специфичным подход к устранению уязвимостей.
      Если кратко — устранение уязвимости не означает перехода на другую версию, а наличие обновленного PHP 5.3.2 не означает наличие дырок которые были и до 5.3.8 и будут после. Поэтому стоит регулярно делать «yum update» а остальную работу сделают за вас в RedHat.
  • +3
    «После таких действий phpMyAdmin будет доступен по пути /phpMyAdmin/»

    забываем про web ботов и дырки в phpMyAdmin'e
    • –4
      Чуть ниже «Теперь один нюанс ».
      На мой взгляд перенос на другой домен — ничуть не хуже перекладывания в другую директорию.
      • 0
        Боты не знают про другой домен. И имя его не угадают, и не узнают — если самому ссылок не давать в паблике.

        А на phpmyadmin, PhpMyAdmin и подобные они долбятся постоянно.

        По этой же причине админы отключают доступ root по ssh — ибо это известное имя, для которого можно подбирать пароль. А в других случаях нужно подобрать и логин и пароль.
        • –2
          Лол. А на что DNS?)
          • 0
            У меня прописана парочка поддоменов, а также * — ссылается на основной домен. То есть, все, что не прописано ломится на ip основного домена, любой поддомен.

            Таким образом, записей нет — а nginx выдает, что надо.

            Лол.
  • +7
    Хорошо посещаемые сайты, 256 ОЗУ и Apache.

    Мне одному кажется что-то странное в этой строке? Где nginx?
    • –3
      Мне эта строка тоже кажется весьма странной.
      Особенно с учетом того что в статье такого не говорится.
  • +4
    Centos-6 86_x64
    на минимальных ресурсах VPS
    А вот тут-то Штирлиц и просчитался…
    • –2
      В чем просчет?
      • +7
        в потреблении памяти x64 vs x32
        • 0
          Мне тоже про x64 вспоминается только в связи с mongodb или кучей памяти.
  • +1
    Use <code>, Luke!
  • +1
    Все таки настоятельно рекомендую сразу смотреть в сторону NGINX(без Apache) + php-fpm.

    Аргумент что примеров для Apache больше чем для nginx очень слабый, а плюсы в будущем очевидны.
    За примерами в крайнем случае можно сходить к ведору или комунити.
  • +1
    Посмотрите хотя бы как люди спасаются от нагрузки простым переходом с Apache + mod_php на nginx + php-fpm http://freehabr.ru/blog/freehabr/410.html
  • 0
    Вопрос.
    Почему eaccelerator, а не APC или Xcache
    Сайт eaccelerator уже давно не работает.
    Я как то спрашивал у знатоков habrahabr.ru/qa/10728/
    • +1
      eaccelerator теперь живет тут sourceforge.net/projects/eaccelerator/, и даже иногда обновляется, правда редко.

      Лично у меня была проблема на MODX Revolution, когда я написал очень замороченный класс, в нем включил еще один и в одном методе то работало, то не работало. Пропарился несколько дней, пока допетрил, что ошибка не в коде, а в APC. Заменил его на eaccelerator — ошибок больше нет.

      Наверняка я сам что-то намудрил, но вот такой случай у меня в практике был.
      • 0
        Не намудрили. Была такая точно такая же тема, при чем именно при включении классов друг в друга. При чем забавно, первый раз заливаешь, пока файл свежий, он 1-2 раза может даже выполниться (скорее 1), а потом сразу оппа и «белый экран» без признаков ошибок вообще. В следующих версиях это уже было поправлено, но осадочек остался.
    • –2
      Предпочитаю разумный минимализм. eaccelerator довольно хорошо работает, есть в репозитории epel для Centos6 и работает «из коробки».
      В случае необходимости — можно подключить еще CentALT (http://centos.alt.ru) там есть довольно много интересного включая apc, xcache и свежий nginx.
      • 0
        А все-таки вы знаете где взять пакет со свежим nginx. Тогда отговорки больше не принимаются. :)
        • +1
          Уболтали. :-)

          Фронтендом.

          [root@test ~]# rpm -ihv centos.alt.ru/pub/repository/centos/6/x86_64/centalt-release-6-1.noarch.rpm
          [root@test ~]# yum install mod_realip2 nginx-stable

          + немного настройки.
          чуть позже (ориентировочно завтра) допишу апдейт к посту.
          • 0
            Не подумайте, что я вас тороплю, просто наследил, чтоб вы не забыли)
  • +1
    Еще один все понял [x]
  • 0
    Посмотрите в сторону BitrixEnv3 который можно развернуть на чистом CentOS 5/6 и получить настроенную систему.

    BitrixEnv3
    BitrixEnv3 Forum
    • 0
      Это такой тонкий юмор?
      • 0
        Нет :)
        Продукт бесплатный, сразу устанавливает 2-х уровневую конфигурацию с nginx в качестве front-end и ZendServer (apache) в качестве back-end. Для кеширования есть возможность использовать memcached.

        Есть консольное меню позволяющее выполнить ряд типовых операций, в том числе добавление нового сайта.
        Использовать можно как для запуска Битрикс, так и для любых других проектов на php.

        На мой взгляд намного проще использовать чем повторить все вышеописанное, да и результат точно будет не хуже.
  • +2
    заменить гайд на lamp + nginx и ещё вместо чистого mysql поставить percona DB — будет замечательно.
  • +1
    файл подкачки корректнее активировать через fstab, а не дергать swapon

    [(15:43):artem@28321-1:~ ] grep swap /etc/fstab
    /swap swap swap defaults 0 0
    • –1
      поддерживаю
      Плюсик, к сожалению, не могу поставить.
    • 0
      Первый раз то можно) Вдруг она еще долго не перезагрузится. Хотя, с такой конфигурацией надо по крону ребутить раз в полчаса))))
      • 0
        в первый раз можно swapon -a
      • 0
        По поводу ребута раз в полчаса — это очень сильное преувеличение. Весь мир довольно долгое время жил на апаче и никто не ребутил сервера раз в пол часа. На данный момент проблем с памятью в данной конфигурации не наблюдается. Хотя нагрузки впрочем тоже.

        21:38:23 up 7 days, 3:16, 2 users, load average: 0.03, 0.03, 0.00
        Mem: 244856k total, 207776k used, 37080k free, 17508k buffers
        Swap: 262136k total, 22112k used, 240024k free, 76164k cached


        Если я не учел какого-то фактора — прошу указать на него. Но на данный момент я не понимаю куда может утечь память.

        Насчет подключения swap — учту и поправлю.

        Насчет необходимости nginx — критика справедливая и правильная. Он необходим. Собственно пониманию проблемы помог комментарий masterbo, за что ему отдельная благодарность. Я как-то считал что на не нагруженных конфигурациях вполне нормально и без него. В секции описания установки nginx сделаю теоретическое отступление.
      • 0
        Ну кто вот минусует. и карму снизили. Первый раз то понятно, что свапоном подключаем, в дальнейшем имеется в виду не писать swapon в rc.local, а использовать идеологически правильный для этого fstab.
  • 0
    А почему не показали benchmark после установки и настройки nginx?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.