Балансировщик — сервер с Nginx на борту:
- занимается балансировкой запросов к серверам приложений (см. ниже);
- занимается обработкой и кэшированием статики (картинки, стили, javascript и т.д.);
- занимается реврайтами;
- может выполнять регулярные «тяжелые» задачи по cron.
Сервер приложения — сервер, на котором выполняется бизнес-логика проекта. В нашем случае это код PHP. На сервере такой роли лучше использовать php-fpm вместо Apache, если нет прямых противопоказаний. Все-таки хороший веб-сервер у нас уже есть. Nginx очень хорошо справляется со своими обязанностями. Главная причина, по которой системные администраторы не спешат отказываться от Apache в качестве бекэнда на «живых» проектах — это наличие файлов .htaccess и, соответственно, куча реврайтов в них. Настоятельно рекомендую потратить время и переписать все реврайты под Nginx. Он делает это гораздо быстрее по своей природе.
Как уже само собой разумеющееся на сервере, выполняющем бизнес-логику должно быть много кэша. Кэшировать нужно все, что можно. У PHP должен быть OPcache или аналог. Использование memcaсhe в проекте всегда приветствуется.
Синхронизировать файлы проекта между серверами приложений можно любым удобным способом. Например lsyncd.
Забегу вперед и скажу, что на серверах приложений обязательно должен быть реализован функционал распределения нагрузки на БД.
Сервер баз данных — сервер с СУБД MySQL на борту. Рекомендую отказаться от использования чистой MySQL и посмотреть в сторону форков, таких как Mariadb и Percona. Для придания отказоустойчивости БД предлагаю посмотреть в сторону кластеризации. У чистой MySQL есть встроенный механизм реализации master-slave репликации. По сути, с его помощью можно реализовать master-master репликацию. Но советовать этого я не буду. Вместо этого предлагаю рассмотреть решение от Percona под названием percona xtradb cluster. Оно реализует настоящую master-master репликацию и полноценный кластер. К тому же он очень прост в управлении, масштабировании и восстановлении в случае сбоя, оснащен встроенным движком xtradb, полностью совместимым с InnoDB. К тому же есть возможность делать резервные копии, которые быстро восстанавливаются, причём гораздо быстрее обычного восстановления из sql дампа. А ребята из Mariadb разработали прекрасную утилиту maxscale для распределения нагрузки между серверами.
Главное правило отказоустойчивости — не допускать наличия единой точки отказа. Т.е. не допускать наличия недублированных узлов. Таким образом, серверов каждой роли у нас должно быть как минимум два. Что касается сервера-балансировщика, то его можно собрать в отказоустойчивый кластер или реализовать Round-robin DNS между несколькими балансировщиками.
По сути, реализуя схему с возможностью горизонтального масштабирования, представленную выше, мы получаем определенный уровень отказоустойчивости. Повышение уровня отказоустойчивости достигается дальнейшим горизонтальным масштабированием, добавляя серверы в нужную роль.
Безопасности много не бывает! Хочу остановиться на базовых моментах:
1. Исключить парольный доступ по SSH/SFTP. Насколько стойким бы ни был ваш пароль, хороший бот-нет обязательно его подберет. Самый удобный, на мой взгляд, способ авторизации — это RSA сертификаты. Просто и удобно.
2. WAF (Web Application Firewall) — незаменимый инструмент на защите вашего сервиса от XSS и SQL-инъекций. При правильной настройке поможет сэкономить много времени и душевных сил.
3. На каждом из серверов обязательно должен быть настроенный Firewall с политикой по умолчанию «Запрещено». Наружу должны быть открыты только необходимые порты.
Для защиты от DDoS атак существует масса способов. Она может осуществляться на уровне хостинга. Некоторые маршрутизаторы обладают возможностью интеллектуальной обработки трафика и очистки его от «мусора». Обычно такая услуга предоставляется провайдерами на платной основе. Тюнинг ядра Linux может помочь устоять перед другими видами сетевых атак.
На примере реального проекта можно проследить, как описанный выше подход может привести в порядок даже очень запущенную систему.
Цель оптимизации
Задачей является крупный интернет-магазин мебели, построенный на CMS Bitrix.
Время генерации некоторых страниц на сайте достигало 200 секунд. Понятно, что при таких условиях пользователь никогда не дождется открытия страницы. Также на некоторых страницах количество запросов на хит достигало 20 000! На серверах, которым была отведена роль выполнения бизнес- логики, были установлены разные версии PHP интерпретатора. Была реализована master-slave репликация, но по факту балансировка не была реализована и работал только один мастер. Данный факт говорил о том, что деньги, выплачиваемые за аренду мощного сервера, не приносили никакой пользы. Серверы БД находились в ДЦ, удаленном от всех других серверов проекта, что накладывало задержку на время соединения более 10 мс. Memcached, установленный на мастер-сервере БД использовался только для хранения сессий, а весь кэш хранился в файлах.
Конфигурация серверов в начале
Парк серверов состоял из 5 довольно мощных машин. Под сервер, несущий на себе Nginx и выполняющий роль мастера для бизнес-логики, был выбран вариант с параметрами Dell PowerEdge R730, снаряженный Intel Xeon E5-2600 v3 2.10GHz Octa-Core, 128 ГБ DDR4 ECC RAM. Этот сервер обрабатывал 90% всех запросов и, судя по значению Load Average, должен был гореть ярким факелом от перегрева. Мастер и слейв БД MySQL находились в виртуальных контейнерах на 1 физическом сервере Dell PowerEdge R730. Как отмечалось ранее, слейв сервер просто реплицировал мастер и не нес никакой нагрузки, а значит ресурсы сервера, отведенные контенеру со слейвом попросту не использовались. Под слейв серверы, выполняющие бизнес-логику использовались две машины с параметрами Intel Core i7-4770, 32 ГБ DDR3 и, можно сказать, не справлялись со своими обязанностями. Также довольно мощный сервер использовался для простого хранения бекапов. На всех серверах использовались SATA диски 6 Гбит/с 7200 об/мин.
В конечном итоге на большинстве серверов не было задействовано и 10% доступных вычислительных ресурсов.
Что было сделано
Было решено использовать новый парк серверов и развернуть там новую архитектуру. После тестирования «переехать» на новые серверы, а от старых отказаться. Оптимальный выбор серверов под каждую роль смог сократить расходы на их аренду. Серверы получились дешевле используемых ранее. Проанализировав размеры данных проекта, было принято решение использовать SSD диски. Они быстрее SATA аналогов и заметно ускоряют файловые операции. Особенно это важно на серверах баз данных. Под хранение бекапов был выделен отдельный сервер-хранилище в соседнем ДЦ. Каждый сервер являлся физической машиной. Виртуализация не использовалась.
Тезисно остановимся на каждой роли: