Как мы сделали это: миллионы просмотров страниц в день, на 60% меньше серверных ресурсов
Как мы перенастроили наше серверное оборудование так, чтобы использовать на 60% меньше вычислительных мощностей и обрабатывать больше конкурирующих запросов, без какого-либо простоя или изменений в коде.
Два года назад в One Mighty Roar мы заметили, что один из неосновных проектов, существующий в компании с первых дней, генерирует значительную часть трафика, несмотря на то, что в него никто не заглядывал уже сто лет. Несколько месяцев мы тратили около 20% нашего времени, которые вскоре вылились в 120% времени, перенастраивая You Rather, мы переделывали всё, начиная с самого основания, создавали API и писали сразу приложения под iOS и под Android.
В итоге, You Rather показал замечательные результаты, заполучил серьёзное признание сообщества и стал великолепным проектом, предметом гордости всей команды One Mighty Roar. Но, как большинство неосновных проектов, он утратил свою позицию в списке приоритетов когда открылись другие новые возможности и перспективы.
В конце этого лета нашей целью стало дать проекту You Rather второе дыхание. Первым шагом стал отказ от устаревшего HTTP-сервера Apache в пользу Nginx. Мы используем Nginx для 99% наших проектов на протяжении более нескольких лет и никогда не жалели об этом (сервер Nginx написан русским разработчиком – Игорем Сысоевым – прим. переводчика). Однако, большую часть нашей работы с Nginx составлял опыт написания файлов конфигурации для новых сайтов и серверов, и мы ни разу не переписывали старые конфигурационные файлы для сайтов, находящихся в продакшене.
В конечном итоге, всего лишь за вечер мы перенесли сайт с более чем 400 активными пользователеями, которые просматривали более 1000 страниц в секунду с Apache на Nginx, причём не было ни секунды простоя сайта.
Сдувая пыль
Что бы у читателя было представление о ситуации: мы – фанаты AWS. You Rather использует каждую крупицу стека AWS от EC2 до EBS, до Route 53, до S3. Для того что бы заполучить тестовое окружение в котором мы смогли бы вести разработку, мы скопировали наш текущий AMI с сайта You Rather и подняли новый инстанс, на котором мы могли в волю пробовать наши трюки и хаки.
Простая команда yum install nginx позволила заполучить готовый работающий Nginx на нашем сервере с CentOS без лишней траты времени. Шаг один: завершено.
Для начала мы подсунули системе нашу стандартную, проверенную конфигурацию для Nginx:
server {
# Port declaration
listen 80 default_server;
listen 443 ssl;
# Server name and aliases
server_name nginx-test.yourather.com;
# Root directory and default index
root /var/www/path/of/yourather/src/;
# Catch-all
location / {
try_files $uri $uri/ /index.php?$args;
}
# Pass the PHP scripts to the PHP-FPM socket
location ~ .php$ {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# PHP-FPM (unix socket)
fastcgi_pass unix:/tmp/php5-fpm.sock;
}
}
И вот, почти всё... просто заработало. Оказалось, что мы изначально сделали большую часть работы, устанавливая AMI с работающими Apache и PHP, переключение и поднятие на Nginx не вызвало проблем. Шаг два: завершено.
Улучшение производительности
Nginx имеет несколько очевидных преимуществ по сравнению с Apache когда дело касается слоя сервера приложений, однако Nginx – не основная причина улучшения производительности сайта You Rather. Чтобы увидеть, почему это так, давайте проясним, что же здесь по-настоящему важно, и что отличает именно You Rather.
Чем реально хорош Nginx – так это тем, что он не обрабатывает файлы «.htaccess». Эти файлы призваны облегчать установку на хостинг вместе с другими проектами или на невыделенные сервера, и обход файловых деректорий в поиске таких файлов происходит при каждом запросе, что становится дорого в плане ресурсов. Nginx, напротив, загружает все конфиги во время первого старта, и всё, приятной работы.
Другим местом, где имелся большой потенциал для улучшения производительности было взаимодействие нашего веб-сервера и PHP. Наша тогдашняя реализация You Rather использовала mod_php вместе c Apache. Хотя первоначальная установка и настройка Apache и mod_php была быстрой и простой, большой недостаток этого подхода в том, что PHP создаёт по процессу на каждый запрос. Выбор в пользу PHP-FPM вместо mod_php дал нам значительный прирост производительности.
Тогда как mod_php интерпретировал PHP как часть процесса Apache и быстро пожирал много ресурсов CPU и памяти, PHP-FPM может быть очень тонко настроен и дать огромное преимущество в производительности. PHP-FPM использует процессы PHP, грамотно запускает и останавливает процессы, Unix-сокеты, использует гранулированный менеджмент процессов. Всё это позволило нам полностью грамотно настроить использование ресурсов на сервере. Теперь, поверх всех этих настроек мы можем менять конфигурацию для Nginx, не затрагивая PHP-FPM и наоборот – это не приведёт к поломке ни того ни другого.
В качестве последней контрольной меры для улучшения производительности PHP мы добавили opcode кэш. Протестировав Zend OPCache и APC мы выяснили, что OPCCache лучше по всем параметрам: повышает скорость обработки PHP и в целом уменьшает потребление памяти.
Шаг три: завершено.
Нагрузочное тестирование
Один приятный бонус, который мы получили в результате трафика с You Rather – это тестирование наших приложений под высокой нагрузкой. Каждый божий день мы испытываем большой скачкообразный рост трафика из-за ссылок в соцсетях, из-за агрегаторов (см. Слэшдот-эффект (англ. Slashdot effect) — мощный всплеск посещаемости веб-сайта, обычно небольшого, после того, как ссылка на этот ресурс появлялась на ленте новостей популярного сетевого издания или блога.) или из-за функий в онлайн магазине приложений. Мы активно используем для тестирования работы под нагрузкой две тулзы: Siege и ab. Здесь мы по большей части использовали Siege.
Так как Nginx обслуживал наш сайт прямо в инстансе где мы вели разработку, настало время нагрузить сервер чтобы увидеть, как он справится с обработкой трафика. При помощи Siege мы смогли увидеть какой уровень нагрузки может обработать единичный инстанс. Огромное преимущество Siege -- это способность нагрузить эндпоинт конкурирующими соединениями, а это превосходно подходит для симуляции реальной работы You Rather. Это легко достигается выполнением команды:
siege -t 1M -c 20 http://nginx-test.yourather.com/
Мы эмулировали работу 20 конкурирующих пользователей (-с 20), которые посылали запросы на сайт в нашем инстансе в режиме нон-стоп в течение минуты (-t 1M). Siege предоставляет превосходную аналитику как во время выполнения тестирования так и по его результатам. Всё выглядело отлично с самого начала тестирования. Загруженность сервера была намного меньше чем на старом Apache AMI и время отклика было в целом меньше.
Мы продолжили играть с настройками Siege, варьируя число конкурирующих подключений от 10 до 100 и более (совет: не используйте более 75 подключений, всё сломается), нагружали разные эндпоинты, например страницу профиля пользователя, страничку необычного вопроса и даже страницу 404.

Мы сравнили результаты работы Siege для инстанса с Nginx с результатами для текущего сайта, работающего под Apache в контрольном инстансе. Если коротко: инстанс с Nginx выполнял на 100% больше транзакций, время отклика на каждую транзакцию было на 50% меньше. И даже лучше: мы увидели самые высокие показатели на сервере с Nginx во время тестирования. Сервер обрабатывал запросы like a boss, слегка отъедая CPU, обрабатывая обрушивающийся поток соединений. Nginx, несомненно, давал сайту так необходимое ускорение.
Выход в свет (Going Live)
Пользуясь всем великолепием, которое из себя представляет AWS мы уже имели балансировщики нагрузки для нашего сайта, так же как и группы для автоматического масштабирования, и правила для отключения нерабочих инстансов и поднятия новых в случае необходимости. Мы всеми способами стараемся поддерживать сайт доступным как можно больше времени, и поднятие новых инстансов под высокой нагрузкой может стать дорогостоящей операцией.
Так как мы создали новый AMI для нового развёртывания сайта, настало время настроить авто-масштабируемую группу, чтобы поднять новый инстанс из нового AMI. Используя AWS CLI всё, что мы сделали – это установили группу для поднятия нового инстанса из нового AMI. Далее, мы выставили в качестве номера желаемого инстанса для группы безопасный номер, который, как мы знали, не должен был привести к падению сайта. Этим самым мы оставлили простор для одновременного сосуществования инстансов Apache и Nginx и балансировки "бок о бок".
as-set-desired-capacity yr-production --desired-capacity 4 --honor-cooldown
Начиная с этого момента, мы медленно отключали старые инстансы на Apache один за другим вручную, позволяя группе авто-масштабирования поднимать новые инстансы на Nginx взамен отключаемых. При этом, согласно Google Analytics, мы ежесекундно имели тысячи просмотров страниц и вызовов API в реальном времени, включая новые сервера под Nginx.
В конце концов, ни одного сервера под Apache не осталось под нагрузкой, и мы начали уменьшать число желаемых инстансов в группе. Начали c 4 и затем до 3... до 2... Мы, возможно, могли бы оставить только одну серверную стойку, но для собственного успокоения оставили две.
Неделю спустя мы сделали некое подобие пост-мортем анализа и посмотрели на показатели. Считаю, что переход на Nginx состоялся:

Наше число инстансов, которое раньше варьировалось, теперь более-менее постоянно, и так уже в течение нескольких недель:

Теперь мы обрабатываем миллионы просмотров страниц и вызовов API при помощи двух инстансов на Nginx, при этом даунтайм 0% в течение полных трёх недель. Прости, Apache, пути назад нет.