Переезд на VPS. Часть 2 – Мои ошибки

17th Декабрь 2011 | Категории: Сервер | Метки: , ,

Прежде чем начать повествование по основной теме, расскажу про свой уровень общения с 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 уников в сутки.

Subscribe without commenting


  1. Dima
    17th Декабрь 2011 в 17:20

    Спасибо Вам за то что вы делитесь ошибками очень ценный опыт!

  2. 18th Декабрь 2011 в 11:30

    сразу нагните сервер тестами ab. Может в ошибки валится.

  3. Тарлюн Максим
    18th Декабрь 2011 в 11:44

    @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уников.

  4. Михаил
    24th Февраль 2012 в 14:57

    Насчет debian-а: Use dotdeb.org, Luke! Там свежайший php.
    Насчет reg.ru: паспортные данные при оплате? ЖЖесть. Пополняешь Qiwi Visa Virtual и оплачиваешь любой европейский VPS. Дешевле и качественнее, особенно если использовать виртуализацию XEN или KVM с реальной памятью, а не как у OpenVZ с виртуальной.

  5. Тарлюн Максим
    24th Февраль 2012 в 15:10

    На счет паспортных данных — все равно. Я варез/парнуху не собираюсь держать на сервере. А в случае чего — могу быть уверен, что сервер мой. И у меня есть доказательство в виде паспорта.
    Европейские VPS… думал… Но передумал… Я искал, читал форумы… Дешевле за аналогичную машинку я видел только на hetzner, но «наслышан» про их сервера.

  6. Михаил
    24th Февраль 2012 в 15:22

    Я даю сканы только в крайних случаях (в банк, при устройстве на работу), в остальных случаях ищу обходные пути/лучшие решения. А то мало ли с какой-нибудь скан-пак за 10$ попадет мой скан :).
    http://www.linode.com/ — это говорят оочень хорошая контора, почитай отзывы. По европейским ценам недешёвые, но они того стоят. И да — не гонись за гигабайтной памятью, на XEN-е потребуется в 2-3 (может и больше) меньше памяти (потому что реальная), да и оверселлингом заняться хостеру трудно с данной виртуализацией. Все кто пробывал VPS-ки на данной виртуализации, OpenVZ обходят за километр.

    Почитай «Как можно снизить потребление оперативной памяти на VPS в 2 раза, ничего не меняя в настройках программ» http://habrahabr.ru/blogs/hosting/53236/