Уменьшение нагрузки на VDS: причины, их поиск и устранение

30 Июня 2016
713

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

  • Увеличение числа посетителей. Вполне естественный фактор для любого коммерческого, или информационного проекта, нацеленного на расширение аудитории.
  • Проблемы с оптимизацией программного обеспечения. Для максимальной производительности все службы, сервисы и утилиты должны быть настроены соответствующим образом, в противном случае доступные ресурсы будут расходоваться впустую.
  • Действия злоумышленников. Спам-боты, сканеры портов, и даже такое, с первого взгляда, безобидное явление, как хотлинкинг - все это заметно сказывается на работе сервера. Кроме того, резкое падение производительности может оказаться признаком DDoS-атаки.

Бороться с первыми двумя мы и научимся в данной статье. Но для начала разберемся, каким образом можно выявить причины медленной работы. 


Мониторинг VDS

Скачок посещаемости наглядно продемонстрирует Яндекс.Метрика, скрипт которой интегрируется непосредственно в движок сайта. Инструмент абсолютно бесплатный, и позволяет узнать:

  • точное число уникальных пользователей, зашедших на сайт;
  • количество просмотров;
  • источники трафика (поисковые фразы, социальные сети, контекстная реклама и другие);
  • время, проведенное пользователем на сайте.

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

Для мониторинга же самого сервера наиболее оптимальным решением можно назвать утилиту atop - небольшую программу позволяющую отслеживать в реальном времени исполняемые процессы и сетевую активность, а также вести лог событий. Устанавливается она командой:


sudo apt-get install atop


Для ее запуска достаточно ввести:


sudo atop 1


Вывод atop разделен на две половины. В верхней секции можно увидеть основную информацию по системе (загруженность памяти, процессора, диска), ниже приводится сводка по каждому процессу. Утилита поддерживает горячие клавиши, что существенно упрощает ее использование:


  • c - распределение процессов по степени нагрузки на ЦП;
  • m - ранжирование по интенсивности расходования памяти;
  • d - сортировка по нагрузке на диск;
  • v - расширенная информация по запущенным процессам (дата и время начала, имя пользователя);
  • u - ранжирование по пользователям, больше всего нагружающим сервер;
  • i, затем указать время в секундах и нажать Enter - позволяет изменить время обновления таблиц (по умолчанию - 10 секунд);
  • g - сброс настроек к дефолтным.

Программа ведет запись собранных данных. Ознакомиться с выводом можно, введя команду:


sudo atop -r


Здесь применимы флаги C, M и D, функция которых аналогична соответствующим горячим клавишам. Например, введя:


sudo atop -r -M


мы отсортируем процессы по степени использования RAM.


Возможности atop позволяют с высокой точностью определить причину падения производительности. Как показывает практика, в большинстве проблемы вызывают неправильные настройки кэширования, интерпретатора PHP, или отсутствие оптимизации баз данных. Давайте разберемся, как их устранить.


Настройка кэширования

В случае заметного роста посещаемости, грамотная настройка кэширования поможет значительно снизить нагрузку на VDS. Рассмотрим решения для Apache и Nginx.

Директивы, управляющие кэшем в Апач, можно прописывать как в файл виртуального хоста, так и в .htaccess корневого каталога вашего проекта. Наиболее простой способ - использование FilesMatch:


<FilesMatch ".(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf|doc|docx)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>


Выше мы задали кэширование всего статического контента, включая мультимедиа и документы. Параметр max-age позволяет указать время хранения в секундах (в данном примере он равен 30 дням).

Больше возможностей предоставляет модуль Expires. Для его активации необходимо сделать следующее:


sudo a2enmod expires
sudo service apache2 restart


В числе преимуществ - возможность точно задать время хранения (запись вида “1 месяц, 3 дня, 2 часа”) и выбрать способ кэширования файла (с момента первого чтения, или модификации). Приведем наглядный пример:

<IfModule mod_expires.c>


Включаем модуль

ExpiresActive On


Задаем кэширование по умолчанию для всех файлов

ExpiresDefault "access plus 1 month"


GIF будут хранится в течение 1.5 месяцев, 3 часов и 10 минут с момента доступа

ExpiresByType image/gif "access plus 1 month 15 days 3 hours 10 minutes"


Картинки JPEG будут сохраняться 2 месяца после последнего изменения

ExpiresByType image/jpeg "modification plus 2 months"
</IfModule>


Обратите внимание: необходимо указывать полные MIME-types файлов, в формате “тип данных/расширение” (image/png, text/css и т.д.).


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


Перечисляем расширения файлов, которые нужно кэшировать

location ~* .(jpg|jpeg|gif|png|ico|css|swf|flv|doc|docx)$ {


Указываем путь к корневой папке сайта

root /var/www/site.ru;
}

Собственно настройками кэширования можно управлять, создав в директории /etc/nginx/conf.d/ файл cache.conf со следующим содержанием:


Указываем директорию кэша

proxy_cache_path /var/cache/nginx


Задаем уровень вложенности папок (1:2:3:4 и т.д.)

levels=1:2


Определяем базовый размер кэша (Мб)

keys_zone=static_cache:100m


Указываем время, после которого кэш удаляется, если не было повторных запросов к файлам (в минутах)

inactive=120m


Задаем максимальный размер кэшируемых данных (Мб)

max_size=500M;


Указываем количество обращений, после которых файл попадает в кэш

proxy_cache_min_uses 1;


После этого убедитесь, что в главном конфигурационном файле nginx.conf имеется следующая строчка:

include /etc/nginx/conf.d/*.conf


В случае отсутствия таковой, пропишите директиву самостоятельно. Чтобы активировать настройки, перезапустите сервер:

sudo service nginx restart


Оптимизация веб-сервера

Одна из наиболее типичных ошибок, допускаемых пользователями - эксплуатация связки LAMP даже в тех случаях, когда этого объективно не требуется. Хотя Apache является весьма популярным и многофункциональным решением, для размещения блога, или сайта-визитки, его возможности оказываются избыточными. Сам сервер слишком тяжеловесен, и потребляет значительные ресурсы. Отсюда - радикальный способ снижения нагрузки на VDS: миграция на более быстрый и оптимизированный Nginx. Если же для нужд проекта требуется именно Апач, Nginx можно установить в качестве фронт-энда, отведя роль прокси-кэш сервера, что также значительно увеличит производительность. Делается это следующим образом:

1. Устанавливаем Nginx:

sudo apt-get install nginx

2. Удаляем дефолтные настройки:

sudo rm /etc/nginx/sites-enabled/default

3. Создаем файл конфигурации для условного проекта site.ru:
 
sudo nano /etc/nginx/sites-available/site.ru

4. Копируем в файл следующие настройки:

server {

  listen 80; root /var/www/site.ru; index index.php index.html index.htm; server_name site.ru; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080; } location ~ /\.ht { deny all; } location ~* \.(jpg|jpeg|gif|png|ico|css|swf|flv|doc|docx)$ { root /var/www/site.ru; }

}


В примере выше мы указали, что все статическое содержимое (изображения, видео, документы) будет кэшироваться и отдаваться пользователю Nginx, на Apache же пойдут только запросы, требующие подключения динамики.

1. Применяем изменения:

sudo ln -s /etc/nginx/sites-available/site.ru /etc/nginx/sites-enabled/site.ru
sudo service nginx restart

2. Меняем порты Apache:

sudo nano /etc/apache2/ports.conf


Здесь необходимо скорректировать следующие строчки:


NameVirtualHost 127.0.0.1:8080
Listen 127.0.0.1:8080


Аналогичная замена осуществляется в конфигурационном файле виртуального хоста:


<VirtualHost 127.0.0.1:8080>


После чего Апач необходимо перезапустить:


sudo service apache2 restart


Настройка PHP

Производительность динамических сайтов можно существенно увеличить, поработав с PHP. Его настройки находятся в файле /etc/php5/apache2/php.ini (если интерпретатор является модулем Apache), либо /etc/php5/fpm/php.ini (для PHP-fpm в связке с Nginx). Многие из них определяются спецификой скриптов, используемых CMS, но есть и несколько, о которых попросту забывают. Тем не менее, даже пара строчек способна заметно снизить нагрузку на VDS. Обратить внимание стоит на следующие директивы:


always_populate_raw_post_data = Off


Ее включение требуется лишь в том случае, если вам необходимо отслеживать нагрузку, создаваемую входящим POST-запросом. Отключение позволит разгрузить оперативную память.


output_buffering = On


Активная буферизация позволит отдавать данные крупными фрагментами, существенно снизив время отклика. В противном случае, сервер будет реагировать на каждую инструкцию echo/print.


; variables_order
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS"


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


date.timezone = Europe/Moscow


Необходимо вручную задать часовой пояс по умолчанию. Если этого не сделать, PHP будет регулярно посылать дополнительные системные запросы для его определения.

После изменения настроек, не забудьте перезапустить Apache:


sudo service apache2 restart


либо службу самого интерпретатора (в случае с Nginx):


sudo service php5-fpm restart


Если на сервере используется PHP версии 5.3 и выше, стоит воспользоваться акселератором скриптов Zend Opcache. Его установка не составляет особого труда:


sudo apt-get install php-pear
sudo apt-get install build-essential php5-dev
sudo pecl install zendopcache-7.0.5


Для загрузки модуля в файл php.ini необходимо добавить строки:


zend_extension=/usr/lib/php5/20100525/opcache.so
opcache.enable_cli=1


Обращаем ваше внимание: начиная с версии PHP 5.5, компонент Zend Opcache уже включен по умолчанию.


Что касается настроек - их следует подбирать, исходя из специфики размещаемых проектов и мощности сервера. Однако даже минимальная рекомендуемая конфигурация поможет ускорить обработку скриптов. Выглядит она следующим образом:


Размер потребляемой памяти для прекомпилируемого кода (Мб)

opcache.memory_consumption=128


Объем памяти для пула строк (Мб)

opcache.interned_strings_buffer=8


Максимальное число скриптов в хэш-таблице (от 200 до 1000000)

opcache.max_accelerated_files=4000


Периодичность проверки актуальности данных (в секундах)

opcache.revalidate_freq=60


Поддержка PHP CLI, используется для отладки, как правило - не нужна

opcache.enable_cli=0


Директивы также вносятся в php.ini после блока активации модуля. Затем следует перезапустить Apache, или сам PHP-fpm:


sudo service apache2 restart
sudo service php5-fpm restart


Оптимизация баз данных MySQL

Как ни странно, это - одна из наиболее простых задач, а все благодаря удобному инструменту Mysqltuner. Скачать последнюю, и наиболее полную версию, можно с официального разработчиков, выполнив несколько команд:


wget http://mysqltuner.pl/ -O mysqltuner.pl
wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt
wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv


Теперь скрипт необходимо запустить с помощью команды:


sudo perl mysqltuner.pl --buffers --dbstat --idxstat --outputfile /tmp/result_mysqltuner.txt


Это позволит получить исчерпывающие сведения о состоянии MySQL, которые будут записаны в текстовый файл /tmp/result_mysqltuner.txt (вы можете задать любое имя и местоположение для отчета). В конце будут изложены советы, следование которым поможет снизить нагрузку на VDS и ускорить работу сайта. Стоит учитывать, что скрипт пригоден для сканирования продакшн-сервера, проработавшего без перерыва не менее 24 часов, в противном случае информация может быть недостоверной.


Рекомендуемые настройки следует внести в файл:


/etc/mysql/my.cnf


Для того, чтобы изменения вступили в силу, нужно перезапустить сервис:


sudo /etc/init.d/mysql restart


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