Если вы работаете с сайтом, который постепенно растет, - увеличивается количество товаров, трафик с рекламы - то рано или поздно придется перейти в режим работы highload, высоких нагрузок на сервер. Но что делать, если ваш сайт не растет, а сервер все чаще не выдерживает, и происходит блокировка данных? Именно с этой проблемой мы столкнулись, дорабатывая сайт для интернет-магазина светового оборудования с ассортиментом более чем 100 000 товаров.
Исходная ситуация
Проект располагался на сервере, у которого было достаточно ресурсов, чтобы обеспечить быструю и бесперебойную работу сайта даже при очень высоких нагрузках. Однако сервер не отвечал на действия пользователей или отвечал очень медленно, как только посещаемость сайта хотя бы немного возрастала.
Поиск проблемы
Мы провели аудит настроек сервера и сайта, разделив работы на два этапа: анализ back-end и front-end, и обнаружили низкую скорость загрузки страниц на back-end’e - порядка 80 секунд на самых посещаемых страницах, что в итоге приводило к существенному снижению конверсии.
Мы выяснили, что основная проблема заключалась в неправильно настроенном кэше и настройке базы данных.
В итоге был составлен план действий из четырех шагов, который помог нам добиться неплохих результатов. Что мы сделали?
Решение
Шаг 1. Настройка баз данных
На первом этапе мы настроили базу данных MySQL без изменения систем хранения, исходя из доступных ресурсов и нагрузки проекта. Эти действия, в первую очередь, были направлены на оптимизацию потребления ресурсов оперативной памяти, что позволило избежать ухода сервера в SWAP, когда, исчерпав ресурсы оперативной памяти, сервер начинал работать из файла подкачки и замедлял работу сайта.
Шаг 2. Смена типа хранения на InnoDB
Почему мы выбрали InnoDB?
В InnoDB данные хранятся в больших совместно используемых файлах, в отличие от используемого прежде MyISAM, где для каждой конкретной таблицы создается отдельный файл данных. InnoDB обеспечивает надежность хранения данных за счет блокировки данных на уровне строки и транзакционности.
Главное преимущество InnoDB заключается в скорости работы – при выполнении запроса к базе InnoDB происходит блокировка только строки, при выполнении же запроса к базе MyISAM блокируется вся таблица. Дело в том, что пока запрос не будет выполнен, никакие другие обращения к таблице/строке будут невозможны. А поскольку строки значительно меньше целых таблиц, InnoDB обрабатывает запросы быстрее.
Также была произведена оптимизация работы самой базы данных InnoDB. Например, были оптимизированы параметры:
# InnoDB parameters
innodb_file_per_table
innodb_flush_log_at_trx_commit
innodb_flush_method
innodb_buffer_pool_size
innodb_log_file_size
innodb_buffer_pool_instances
innodb_file_format
innodb_locks_unsafe_for_binlog
innodb_autoinc_lock_mode
transaction-isolation
innodb-data-file-path
innodb_log_buffer_size
innodb_io_capacity
innodb_io_capacity_max
innodb_checksum_algorithm
innodb_read_io_threads
innodb_write_io_threads
Промежуточные результаты
После выполнения шагов 1 и 2 количество одновременных соединений с веб-сервером уменьшилось, так как запросы к базе данных и подключение к ней стали обрабатываться быстрее.
Это в свою очередь привело к уменьшению потребляемой оперативной памяти.
Шаг 3. Перенастройка Nginx и установка модулей кэширования brotli, pagespeed, proxy_buffering
Nginx позиционируется как простой, быстрый и надежный сервер, неперегруженный функциями. Уже длительное время Nginx обслуживает серверы многих высоконагруженных российских сайтов, например, Яндекс, Mail.Ru, ВКонтакте и Рамблер. Для улучшения производительности при использовании дополнительных серверов, Nginx поддерживает буферизацию (proxy_buffering) и кеширование (proxy_cache), чем мы и воспользовались.
Не обошлось и без курьезов настроек Nginx. У клиента был обычный интернет-магазин с товарами, тогда как настройки буферизации, которые мы обнаружили во время аудита, позволяли ему быть чуть ли ни стриминговым сервисом. Мы существенно уменьшили значения в параметре client_max_body_size, что в совокупности с перенастройкой Nginx еще больше снизило потребление памяти.
Шаг 4. Оптимизация настроек PHP-FPM и Memcache и отключение Apache
PHP-FPM нередко используется в паре с веб-сервером Nginx. Последний обрабатывает статические данные, а обработку скриптов отдает PHP-FPM. Такая реализация работает быстрее, чем распространенная модель Nginx + Apache.
Скорость обработки запросов Apache ниже. Например, Apache приходится каждый раз считывать несколько конфигурационных файлов на сервере, затрачивая системные ресурсы и время. В итоге мы решили просто отключить Apache, который ничего не обслуживал, а только потреблял ресурсы.
Необходимым шагом стал перевод работы PHP-FPM на unix socket. Зачем это понадобилось? Nginx сам по себе довольно быстрый веб-сервер, однако самостоятельно он не может обрабатывать скрипты. Для этого необходим бэкенд в виде PHP-FPM. Чтобы вся эта связка работала без потери скорости, мы использовали unix socket – способ подключения к PHP-FPM, позволяющий избегать сетевые запросы и дающий значительный прирост в скорости работы сайта.
Результаты работ
1. Время отклика главной страницы уменьшилось с 24 секунд до чуть более 3 секунд, внутренних до 5-8 сек.
2. Уменьшилось потребление серверных ресурсов.
3. Стабилизировалось поведение сервера - он перестал зависать.
4. Глубина просмотров увеличилась на 30%, и как следствие, это дало улучшение в SЕО, а также последующих продаж: растут поведенческие показатели => растут позиции сайта в выдаче => растет трафик => растут продажи.
5. Клиенту были даны рекомендации по оптимизации front-end части сайта для ускорения работы сайта. Например:
оптимизировать графики и настройку выдачи изображений в формате webp;
настроить lazyload-загрузки данных;
вынести все некритические для отображения страницы скрипты в конец страницы.
Вывод
Мы ускорили сайт и устранили проблемы с его загрузкой без изменения кода. Скорость работы сайта влияет на многие показатели: начиная с удобства для пользователя и заканчивая ранжированием сайта в поисковой выдаче, что в конечно итоге сказывается на конверсии.