Переезд на VPS. Часть 2 – Мои ошибки
Прежде чем начать повествование по основной теме, расскажу про свой уровень общения с nix* системами. Больше года основной операционной системой была Ubuntu. Если на рабочем месте видел представителя nix’овых – не плевался. Я не повелитель командной строки, и до сих пор мне проще скопировать файлы через mc и отредактировать в gedit. Но я хорошо умею пользоваться поиском и находить ответы на возникающие вопросы. Если у вас нулевой опыт в общении с linux, и вы не умеете гуглить – забудьте сразу про самостоятельное администрирование.
В прошлый раз я выбирал хостинг и тариф. Нам все равно надо устанавливать ОС и софт. Продолжим повествование.
Часть 3. Выбор ОС
Для начала определимся: «а что вообще надо?». Попробуем логически выбрать операционку. Моя интуиция мне подсказывает, что если на сервере менее 4Gb оперативки, то не зачем использовать 64-битные ОС.
Дальше семейство: Linux или FreeBSD. Мне кажется, что сейчас это просто дело вкуса, и сервер с софтом можно настроить примерно одинаково, вне зависимости от того, linux это, или freebsd. Так как с linux у меня есть хоть какой-то опыт – выбор очевиден. Windows оставим для десктопов и .NET программистов.
Не мог не вставить анекдот:
Дочка Убунту прибежала к Дебиану и, весело смеясь, поцеловала его в лоб: "С днём рождения, папа!"
Затем она окинула радостным взглядом сидящих за столом гостей и спросила своим звонким голосом:
— Папа, а где Gentoo, разве он ещё не пришёл?
— Нет доченька, он ещё только собирается!
Дальше выбираем дистрибутив: Gentoo – сразу не для нас. По крайней мере, не на начальном уровне. Остаётся:
Suse, Fedora – ничего про них не слышал, пропускаем.
Centos, Debian, Ubuntu – последняя у меня ассоциируется с десктоп системами, поэтому её пропускаю. Изначально выбрал Debian. Но потом перешел на Centos. Но об этом ниже.
Часть 4. Выбор Софта
Обязательно должно было быть установлено: PHP 5.3, eAccelerator, MySQL, Nginx.
На выбор: Apache / php-fpm.
Дополнительно: мониторинг сервера.
До всей этой затеи у меня где-то на уровне подкорки уже было отложено, что Apache – медлительная херня, и его нужно выкидывать. Чуть-чуть поискав, нашел хорошую статью про связку из nginx + php-fpm.
В качестве утилиты для мониторинга был выбран Munin – не в последнюю очередь из-за своей простоты.
Если вы последуете моему примеру, то учитывайте, что по инструкции «с нуля до работающего состояния» установить можно, но вот настраивать весь софт под вашу конфигурацию – все равно придется.
Часть 5. Первая инструкция идет в ведро
Итак, используя статью про то, как поднимают на Debian5 связку nginx + php-fpm вроде все установил. Но вот беда: в репозиториях Debian5 по умолчанию находится PHP 5.2.6. Как я ни старался подключить более новый репозиторий и поставить PHP 5.3, так и не вышло ничего. Итог – переустановка из панели управления с Debian5 на Debian6. Но там что-то сразу пошло не так. Итог – инструкция идет в ведро.
Часть 6. Centos6 + Apache
Поискав еще немного, нашел хорошую инструкцию про разворачивание всего необходимого на Centos. Минусом было использование Apache. Кому интересно – вот ссылка. Прошла уже неделя, и я уже не помню, где тогда накосячил, но помню, что я через панель управления переустанавливал Centos6 дважды. В итоге, не без кучи FAIL’ов, установил 32-битный Centos6 и требуемый софт.
Часть 7. FAIL установки
1. Опечатки консольных команд.
В качестве примера команда из статьи, как она отображается в браузере:
[root@test ~]# rpm -ihv download.fedora.redhat.com/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm |
Здесь новичок может допустить сразу 2 ошибки. Во-первых, команду надо скармливать консоли без #, то есть все, что начинается с rpm… А второе – парсер хабра съел http://
и поэтому команда не сработает:
[root@tarlyun ~]# rpm -ihv download.fedora.redhat.com/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm error: open of download.fedora.redhat.com/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm failed: No such file or directory |
Правильный синтаксис команды:
rpm -ihv http://download.fedora.redhat.com/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm |
2. Увеличиваем память для eAccelerator.
Уже на рабочем сервере, когда все сайты были запущены. Поменял в конфиге значение с 0 (по умолчанию 32 или 64 Мбайта) на 128. Перезагружаю апач и получаю:
[root@tarlyun ~]# service httpd restart Stopping httpd: [FAILED] Starting httpd: (98)Address already in use: make_sock: could not bind to address 127.0.0.1:8080 no listening sockets available, shutting down Unable to open logs [FAILED] |
Всё. Сайт в дауне. Вечером. В самый час пик. Сразу адреналин. Быстро гуглим:
Apache не может запуститься, так как на его порту (8080) уже кто-то висит. Задача – найти, убить (kill + id процесса). И перезапустить Apache:
[root@tarlyun ~]# lsof -i :8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 14153 apache 3u IPv4 318443902 0t0 TCP localhost:webcache (LISTEN) [root@tarlyun ~]# kill -9 14153 [root@tarlyun ~]# service httpd start Starting httpd: [ OK ] |
В итоге – так и не смог дать больше ОЗУ для eAccelerator. Откатился на старые настройки.
3. MySQL Daemon failed to start.
Случилось также на работающем сервере. Настраивая конфиг для более оптимального выполнения MySQL, получил:
[root@tarlyun mysql]# /etc/init.d/mysqld restart Stopping mysqld: [ OK ] MySQL Daemon failed to start. Starting mysqld: [FAILED] |
Опять же. Адреналин. Google. Понимаю, что надо глянуть лог ошибок:
/var/log/mysqld.log:
111209 8:17:14 [ERROR] /usr/libexec/mysqld: Error while setting value 'ON' to 'query_cache_type'
111209 8:17:14 [ERROR] Aborting
И сразу все становится понятно (по крайней мере понятно, что приводит к крушению):
query_cache_type = ON
Удаляем строку из конфига. И запускаем нормально MySQL.
4. Apache. prefork vs worker.
Особо не вчитываясь, изначально настраивал секцию # worker MPM, оставив prefork со значениями по умолчанию. Через пару дней, когда стал более детально разбирать конфиг и определять, что есть что, понял что ошибся.
Узнать, что использует Apache, можно командой:
[root@tarlyun ~]# httpd -V | grep MPM Server MPM: Prefork -D APACHE_MPM_DIR="server/mpm/prefork" |
Как видно из ответа, используется prefork.
5. tzdata.
В октябре 2011 года в России отменили переход на зимнее время. За информацию обо всех стандартах времени всех стран отвечает tzdata.
Выполнив команду date, я увидел, что время на 1 час меньше (реально было 15:38).
[root@tarlyun]# date Tue Dec 6 14:38:33 MSK 2011 |
Обновляем пакет:
[root@tarlyun]# rpm -Uvh http://mirror.centos.org/centos/6/extras/i386/RPMS/centos-release-cr-6-0.el6.centos.i686.rpm [root@tarlyun]# yum update tzdata |
Проверить текущую версию пакета можно командой:
[root@tarlyun]# rpm -qa |grep tzdata tzdata-2011l-4.el6.noarch |
И еще раз date:
[root@tarlyun]# date Tue Dec 6 15:44:16 MSK 2011 |
ps. После всех манипуляций ничего не произошло. Я уж думал что это очередной FAIL. И от безысходности создал тикет системному администратору. На что неожиданно получил ответ: «Проблема исправлена, приносим свои извинения за доставленные неудобства». Причем сервер не перезагружали. Всё заработало само.
8. MEGA FAIL – опечатка в паспортных данных.
На reg.ru я зарегистрировался в день начала продаж двубуквенных доменов в зоне su. Сказать, что я тогда торопился – ничего не сказать. К слову, я сделал заявку на 4 домена, но успел только с двумя. В общем, я допустил аж 2 опечатки в своих данных: цифра в серии паспорта и опечатка в названии города. При оплате сервера необходимо предоставить скан документов, удостоверяющих личность владельца. Если этого не сделать, то сервер будет работать в ограниченном режиме – канал 64 Кбит и запрет на исходящую почту.
Сервер я заказал в пятницу днем. Сразу же прикрепил документы. И пошел по своим делам. Вечером обнаружил, что «документы не соответсвуют, верификация не пройдена». И конечно же, я обнаружил опечатки. В выходные дни менеджеры не работают. Да, есть поддержка по доменам, хостингу, серверам. Но у людей, ответственных за проверку документов – выходной.
В итоге ограничения с сервера сняли только во второй половине дня понедельника. Вот так вот было потеряно 3 дня.
9. You have new mail in /var/spool/mail/root
Не столько ошибка, сколько просто надоедающая надпись, которая появляется после любой команды в консоли. Удаляем ручками текущую почту, а все остальное перенаправляем на любой ящик командой:
echo "ваша@почта" > /root/.forward |
10. mysqldump Terminated / Killed
При переносе сайтов с одного сервера на другой необходимо сделать дамп баз. Проблемы возникли с основной БД размером в 1,2 Gb. Ограничения по нагрузке shared-хостинга просто убивали mysqldump
на 10-20%:
lgndru@xxx ~ $ mysqldump -uuser -ppass db_name > db_name.sql Terminated lgndru@ xxx ~ $ mysqldump -uuser -ppass db_name | gzip -c > db_name.sql.gz Killed |
Оставалось 2 варианта. Бэкапить базы данных, ручками прописывая названия таблиц, этот вариант сразу отпадал: вводить названия 400 таблиц – удовольствие не из приятных. Bash скрипт писать не хотелось. Ну и второй вариант – выполнять дамп с одного сервера на другой. То есть, находясь на новом сервере выполнить команду:
ssh lgndru@lgnd.ru mysqldump -uuser -ppass db_name > db_name.sql |
У нас запросят пароль от старого сервера, и мы получим весь дамп на новом сервере. Даже копировать ничего не надо. Останется только влить данные в mysql:
mysql -uuser -ppass db_name < db_name.sql |
Позже потребовалось перенести повторно одну таблицу со старого сервера на новый. Захотел всё сделать без создания промежуточных файлов, с помощью одной команды, которая методом тыка получилась такой:
[root@tarlyun ~]# ssh lgndru@lgnd.ru mysqldump -uuser -ppass db_name --tables pl_diag | mysql -uroot -ppass db_name |
11. Munin и графики.
Всех ошибок и не пересчитать.
Думал поседею, пока настрою «простой и легкий» монитор производительности, каковым именуют Munin. Из того, что я запомнил:
– Необходимо все действия выполнять от пользователя munin
, а то кердык правам, и процесс не сможет получить доступ к графикам. В Centos запустить консоль для пользователя munin
можно так:
[root@tarlyun ~]# su - munin --shell=/bin/bash |
– Можно получить подсказку от munin командой
[root@tarlyun ~]# su - munin --shell=/bin/bash -bash-4.1 $ munin-node-configure --suggest --shell |
Мне посоветовали добавить следующее:
ln -s '/usr/share/munin/plugins/munin_stats' '/etc/munin/plugins/munin_stats' # The following plugins caused errors: # diskstats: # Non-zero exit during autoconf (1) # irqstats: # Non-zero exit during autoconf (1) # tomcat_: # Non-zero exit during autoconf (127) |
Все три плагина были удалены из каталога плагинов (разбираться не стал, что и зачем). Требуемая символическая ссылка была создана.
– Также стоит настроить MySQL (прописать имя пользователя и пароль), apache (включаем server-status) и nginx (скачиваем плагины и разрешаем вывод статистики для munin) – но это тема отдельной статьи.
Часть 12. FAIL программ.
1. PHP Warning: date()…
Типичная ошибка для PHP5.3. Полный текст ошибки:
PHP Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Europe/Moscow' for 'MSK/4.0/no DST' instead in Command line code on line 1 |
Необходимо в php.ini
прописать рекомендуемую временную зону:
date.timezone = 'Europe/Moscow'. |
Проверка, из консоли наберем команду:
[root@tarlyun ~]# php -r "echo date('Y-m-d H:i:s');" 2011-12-06 15:48:48 |
Всё в порядке.
2. CodeIgniter v1.7.1
Так как основной проект написан на нём, то меня встретила надпись:
A PHP Error was encountered
Severity: 8192
Message: Function set_magic_quotes_runtime() is deprecated
Filename: codeigniter/CodeIgniter.php
Line Number: 60
A PHP Error was encountered
Severity: 8192
Message: Assigning the return value of new by reference is deprecated
Filename: libraries/Loader.php
Line Number: 255
Для начала обновляемся до 1.7.3. Ошибки должны исчезнуть у большинства.
3. CodeIgniter v1.7.3. The URI you submitted has disallowed characters.
Уж не помню, где и откуда я брал расширение для стандартной библиотеки URI (которая позволяла писать в URL кириллицу), но из-за него при запросе любой страницы выпадало сообщение: The URI you submitted has disallowed characters
. После двух чашек кофе ошибка была локализована: MY_URI, которую я использовал, базировалась на версии 1.7.0. Регулярка на определение валидности URL была такой:
if ( ! preg_match("|^[".preg_quote($this->config->item('permitted_uri_chars'))."]+$|i", rawurlencode($str))) |
В PHP версии 5.3 поменяли поведение функции preg_quote – теперь она экранирует символ «-». В общем, необходимо было чуточку подправить предыдущую регулярку, убрав излишнее экранирование:
if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", rawurlencode($str))) |
4. phpBB – Could not get style data
Я использовал форум phpBB в двух проектах. Сразу после переноса получил такую надпись на всех страницах. Помогла очистка кэша и выставление правильных прав для папки с кэшем.
5. WordPress
Не обошли стороной неприятности и этот блог. После установки всех прав я получил в админке сообщение, что плагин sitemapXML
не может получить доступ к каким-то каталогам (к сожалению, не записал), хотя на все требуемые места поставил права 777 (изначально было 660 и 775). Пошел гуглить. Нашел хороший плагин, который проверяет правильность выставленных прав доступа WP Security Scan. Попытался его установить из админки – и wordpress попросил указать пароль к FTP! Это было перебором. Погуглив еще, обнаружил обсуждение данной проблемы. WordPress плохо себя чувствует, когда выполняется не из-под главного пользователя Apache (apache
или www-data
)
В итоге сменил владельца и всё заработало:
chown -R apache:apache /var/www/sites/tarlyun.com/public_html |
6. Apache server-status + wordpress
Не знаю, стоило или нет так делать. В настройках я указал сайт по умолчанию. При прямом доступе по IP к серверу он будет отдавать этот блог. Из-за своего htaccess
, который перехватывает все запросы, Apache не может отобразить свою статистику по адресу: http://31.31.201.254/server-status
. Всё это лечится добавлением одной строки в htaccess
:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_URI} !=/server-status
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
По поводу безопасности не стоит волноваться. Вы не можете открыть http://31.31.201.254/server-status
. Так как стоит ограничение доступа по IP.
Чтобы не было эпичных FAIL’ов, стоит ограничивать доступ по IP ко всем важным ресурсам: статистика, логи сервера, phpMyAdmin. Если у вас IP динамический, то всё же стоит раскошелиться на постоянный.
На этом все. Чуть позже мы обязательно вернемся к настройке сервера. Обязательно поговорим про Munin. А пока с серверами достаточно. Пора программировать.
PS. Третий день в полную нагрузку – полёт нормальный. Посмотрел на некоторые графики. Увидел потенциальные места оптимизации, в том числе и кода. Посещаемость всех проектов 3000 уников в сутки.
Спасибо Вам за то что вы делитесь ошибками очень ценный опыт!
сразу нагните сервер тестами ab. Может в ошибки валится.
@IAD
Я уже при написании статьи вспомнил про ab. В идеале — перед любыми изменениями настроек сервера — надо гонять ab. Хотя для построения полной картины — нужно что то типа селениума. Нужна имитация действий пользователя, что и MySQL досталось.
Посмотрим, может возьму в тестирование аналогичный сервер и попробую настроить с нуля, тестируя каждый шаг.
Сейчас данные:
ОЗУ 700Мб/1000Мб занято. Ни разу сервер больше 800Мб не отъедал. Есть запас для MySQL/MemCache/eAccelerator/Apache
LoadAverage держится в районе 0.1-0.2, поднимаясь до 0.3 только в момент утренней загрузки MySQL дампа в размере 800Мб.
Это при том, что за неделю с 9по16 декабря на lgnd.ru было:
23 609 Посещения
6 312 Уникальные посетители
249 233 Просмотры страниц
Даже на текущих настройках сервер выдержит 5000-6000Уников в день. А при тюнинге и грамотном кэшировании — 10000уников.
Насчет debian-а: Use dotdeb.org, Luke! Там свежайший php.
Насчет reg.ru: паспортные данные при оплате? ЖЖесть. Пополняешь Qiwi Visa Virtual и оплачиваешь любой европейский VPS. Дешевле и качественнее, особенно если использовать виртуализацию XEN или KVM с реальной памятью, а не как у OpenVZ с виртуальной.
На счет паспортных данных — все равно. Я варез/парнуху не собираюсь держать на сервере. А в случае чего — могу быть уверен, что сервер мой. И у меня есть доказательство в виде паспорта.
Европейские VPS… думал… Но передумал… Я искал, читал форумы… Дешевле за аналогичную машинку я видел только на hetzner, но «наслышан» про их сервера.
Я даю сканы только в крайних случаях (в банк, при устройстве на работу), в остальных случаях ищу обходные пути/лучшие решения. А то мало ли с какой-нибудь скан-пак за 10$ попадет мой скан :).
http://www.linode.com/ — это говорят оочень хорошая контора, почитай отзывы. По европейским ценам недешёвые, но они того стоят. И да — не гонись за гигабайтной памятью, на XEN-е потребуется в 2-3 (может и больше) меньше памяти (потому что реальная), да и оверселлингом заняться хостеру трудно с данной виртуализацией. Все кто пробывал VPS-ки на данной виртуализации, OpenVZ обходят за километр.
Почитай «Как можно снизить потребление оперативной памяти на VPS в 2 раза, ничего не меняя в настройках программ» http://habrahabr.ru/blogs/hosting/53236/