О чем статья

Когда дело доходит до запуска PHP-приложений, выбор правильного веб-сервера критически важен. Чтобы достоверно оценить производительность популярных серверов мы тестировали их не на синтетических, а на реальных данных. Мы не хотели составлять свой рейтинг веб-серверов для запуска php-приложений. Нашей задачей было показать условия, при которых тот или иной веб-сервер продемонстрирует лучшие результаты.

Приложения для запуска php: 30 лет эволюции

В начале был CGI. Это была одна из первых технологий для запуска серверных скриптов, появившаяся в 90-х. CGI поддерживает разные языки, что делает этот интерфейс весьма универсальным, но со своими недостатками. Например, на каждый запрос сервер создает отдельный процесс для каждого CGI-скрипта, что приводит к перерасходу системных ресурсов и сильно сказывается на производительности и скорости ответа сервера. Известной проблемой также является запуск скрипта с правами пользователя веб-сервера. Т.е. при неправильной настройке сервера CGI-скрипт может получить доступ не только к файлам и ресурсам другого приложения, но и к логам и конфигурации сервера, что создает потенциальную уязвимость.

Чтобы решить эти проблемы, был разработан Apache и модуль mod_php, который позволил запускать PHP-код непосредственно внутри веб-сервера и настроить индивидуальные права доступа к файлам для каждого хоста. Хотя на каждый запрос по-прежнему создавался отдельный процесс, часть данных кэшировалась, что существенно ускоряло выполнение по сравнению с CGI.  Это давало значительный прирост в скорости.

Apache + mod_php стал популярен благодаря своей простоте конфигурации. Apache до сих пор является одним из популярных веб-серверов для web и часто используется для создания чего-то на скорую руку и без особого конфигурирования.

Статистика популярности веб-серверов.png

Популярность и доли рынка web-серверов.

Но использовать  Apache для отдачи статики не лучшее решение: даже для получения картинки будет использован «тяжелый» (со всеми модулями вроде mod_php) обработчик.

Хорошей практикой считается использование Apache вместе с Nginx. Nginx эффективно справляется с отдачей статики, а запросы требующие выполнения php кода перенаправляет на Apache. Это значительно уменьшает потребление памяти и повышает скорость обработки запросов.

Схема обработки запроса сервером.png

Схема обработки запроса web-сервером.

Связка Nginx и Apache с mod_php дает значительный прирост производительности, но модуль mod_php имеет узкое место: он запускает интерпретатор php в контексте каждого процесса Apache, что сильно увеличивает использование ресурсов.

Для более эффективного выполнения php был разработан PHP-FPM (FastCGI Process Manager) — это расширенная версия FastCGI, разработанная для увеличения производительности и надежности в средах с высокой нагрузкой. В отличие от mod_php, FPM запускает пул рабочих процессов, которые обслуживают запросы независимо от самого веб-сервера. Нужно иметь в виду, что для получения максимального быстродействия требуется детальная настройка. Также стоит учесть что некоторые CMS (WordPress, 1С-Битрикс: Управление сайтом) потребуют дополнительного конфигурирования так как часть правил хранится в файлах .htaccess (т.е. рассчитаны на запуск именно через Apache).

Можно ли что то еще сделать для ускорения работы PHP-скриптов? Этот вопрос задал себе не один разработчик. В поисках решения были найдены технологии, которые кардинально изменили подход к обработке запросов:

  • Поддержка долгоживущих процессов. В отличии от традиционного подхода где приложение инициализируется каждый раз при новом запросе, можно один раз загрузить все приложение в память и использовать для обработки входящих запросов.

  • HTTP-сервер на уровне приложения. Устраняет дополнительный слой между сервером и приложением, снижая накладные расходы.

  • Многопоточность. Позволяет приложениям обрабатывать больше запросов одновременно в рамках одного процесса.

  • Минимизация накладных расходов на взаимодействие с FastCGI. Убирая взаимодействие с FastCGI и работая с php кодом нативно мы устраняем накладные расходы на обработку каждого запроса.

Рассмотрим плюсы и минусы некоторых способов запуска php приложений:

1. Apache + mod_php

Создатель: Apache Software Foundation. Написан на C.

Плюсы:

  • Лёгкость настройки. mod_php включен в в стандартную сборку apache.

  • Стабильность. Решение проверено временем и имеет большую базу готовых проектов.

Минусы: 

  • Ресурсоемкость. Модуль загружается внутри каждого процесса Apache, что сильно влияет на производительность.

  • Большое увеличение потребляемых ресурсов при высоких нагрузках.

  • Отсутствие гибкости. Не позволяет тонко настроить конфигурацию для каждого виртуального хоста или разделение ресурсов между процессами.

2. PHP-FPM (PHP FastCGI Process Manager)

Создатель: Андрей Павлин. Написан на C.

Плюсы:

  • Стал официальной частью PHP, начиная с версии 5.3.

  • №2 в списке популярных способов запуска PHP-приложений.

  • Обладает неплохой производительностью за счет масштабирования пула воркеров.

  • Возможность гибкой настройки пула.

  • Больше возможностей для отладки, включая лог медленных запросов.

Минусы:

  • Более сложная настройка по сравнению с Apache(mod_php). 

  • Необходимо настроить взаимодействие с веб-сервером (Nginx).

  • Ресурсоемкость: Каждый запрос обрабатывается отдельным PHP-процессом, что увеличивает расход оперативной памяти при высокой нагрузке. Также присутствуют накладные расходы из-за коммуникации через FastCGI.

3. PHP-PM (PHP Process Manager)

Создатель: Марк Шличтенмайер. Написан на PHP.

Плюсы:

  • Поддержка долгоживущих процессов. Вследствие чего производительность лучше чем у php-fpm.

  • Асинхронная обработка. PHP-PM использует ReactPHP для обеспечения асинхронности, что значительно ускоряет обработку запросов.

  • Автоматическая перезагрузка при изменении кода.

Минусы:

  • Необходимо следить за памятью. 

  • Требует более глубокого понимания работы асинхронного PHP.

  • Небольшое сообщество.

  • Меньше совместимости: Не поддерживает все библиотеки и расширения, использующие синхронные механизмы, такие как PDO или CURL, которые по умолчанию работают в синхронном режиме.

4. FrankenPHP 

Создатель: Кевин Дюнглас. Написан на Go.

Плюсы:

  • Поддержка долгоживущих процессов.

  • Нет необходимости в отдельном веб-сервере.

  • Поддерживает асинхронную обработку запросов.

  • Поддержка WebSocket и длительных соединений.

  • Поддерживается в laravel octane (библиотека позволяющая одной командой установить Swoole, RoadRunner или FrankenPHP, без необходимости писать код воркера) (https://github.com/laravel/octane).

Минусы:

  • Необходимо следить за памятью.

  • Необходимо перезапускать при изменении кода.

  • Требует более глубокого понимания работы асинхронного PHP.

  • Небольшое сообщество.

  • Без использования laravel octane необходимо написать код для воркера.

  • Сложная настройка. Требует более сложной настройки и внедрения в существующие проекты по сравнению с традиционными решениями например php-fpm.

5. RoadRunner

Создатель: Spiral Scout. Написан на Go.

Плюсы:

  • Поддержка долгоживущих процессов.

  • Нет необходимости в отдельном веб-сервере.

  • Асинхронность и многопоточность: поддерживает асинхронные задачи.

  • WebSocket и gRPC: Поддерживает WebSocket, gRPC и очереди для построения реальных асинхронных приложений.

  • Поддерживается в laravel octane.

Минусы:

  • Необходимо следить за памятью.

  • Необходимо перезапускать при изменении кода.

  • Требует более глубокого понимания работы асинхронного PHP.

  • Небольшое сообщество.

  • Без использования laravel octane необходимо написать код для воркера.

  • Сложная настройка.

6. Swoole

Создатель: Swoole Team. Написан на C.

Плюсы:

  • Поддержка долгоживущих процессов.

  • Нет необходимости в отдельном веб-сервере.

  • Поддерживает асинхронный ввод/вывод и корутины, и может обрабатывать высоко-конкурентные запросы.

  • Поддержка множества сетевых протоколов, таймеров, управления процессами, управления памятью и других функций, отвечающих различным потребностям разработки.

  • Поддерживается в laravel octane.

Минусы:

  • Необходимо следить за памятью.

  • Необходимо перезапускать при изменении кода.

  • Требует более глубокого понимания работы асинхронного PHP.

  • Небольшое сообщество.

  • Без использования laravel octane необходимо написать код для воркера.

  • Сложная настройка.

7. NGINX Unit

Создатель: NGINX. Написан на C.

Плюсы:

  • Unit поддерживает не только PHP, но и другие языки, такие как Python, Go, Perl и Ruby.

  • Поддерживает динамическую смену конфигурации без перезапуска сервера.

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

  • Минимизирует время простоя и облегчает управление конфигурациями.

  • Не требуется изменять приложение как в случае с долгоживущими процессами.

Минусы:

  • Меньшая производительность по сравнению с решениями для долгоживущих процессов.

  • Небольшое сообщество: Unit менее популярен по сравнению с традиционными решениями вроде PHP-FPM.

  • Ограниченные возможности для асинхронности: Хотя Unit поддерживает несколько языков и конфигураций, он все еще уступает в плане асинхронных возможностей таким решениям, как Swoole или RoadRunner.

Сравнение скорости приложений

На тему сравнения скорости приложений для запуска PHP написано множество статей и проведена уйма тестов. Например:

  1. Сравниваем PHP FPM, PHP PPM, Nginx Unit, React PHP и RoadRunner

  2. Тест производительности во время выполнения PHP

  3. Mod_php vs php-fpm Performance Benchmark [Surprising Results]

  4. Apache & PHP system resource usage | mpm_prefork + mod_php vs. mpm_event + php-fpm

Однако большая часть таких тестов являются сильно синтетическими, т.е. тестируемые проекты мало похожи на то, с чем вы в итоге будете иметь дело (например, первая статья, где сервер отвечает json`ом без запросов к БД или вторая, где тестируется phpinfo). Чтобы сделать тесты более реалистичным мы взяли интернет-магазин на базе Laravel (Laravel Framework 10.41.0) — Bagisto (v2.2.2). Сгенерировали 5000 товаров и настроили его в соответствии с инструкциями по развертыванию (включен кэш и отключен различный дебаг). 

Env-переменные

Параметр

Значение

APP_ENV

production

APP_DEBUG

false

RESPONSE_CACHE_ENABLED

true


Кэширование конфигов и роутов

  • «php artisan optimize»

Среда тестирования


Virtualization

WSL

CPU

8 cores (2.8GHz)

RAM

8Gb

OS

Ubuntu


Конфигурация MySQL


Параметр

Значение

tmp_table_size

512M

max_heap_table_size

512M

sort_buffer_size

64M

read_rnd_buffer_size

1M

max_connections 

500

max_user_connections 

500


Все контейнеры и результаты замеров опубликованы в нашем GitHub.

Инструменты тестирования

Само тестирование проводилось с помощью Yandex Tank при следующей конфигурации:


  load_profile:
    load_type: rps
    schedule: line(10, 300, 60s) const(100, 60s)
  instances: 300

В данном случае мы явно ограничивает Yandex Tank в количестве инстансов, чтобы не добиться появления 110 кодов ответов, а проверить какой RPS способен выдавать сервер в заданной конфигурации.

В рамках тестирования мы проверяли следующие сервера приложений:

  • Apache(mod_php)

  • PHP-FPM

  • FrankenPHP

  • RoadRunner

  • Swoole

  • Nginx-UNIT

PHP-PM не участвовал в сравнении так как последний релиз был в 2022 и сейчас часть классов из пакета React\Http не совместима с новыми версиями Psr\Http.

Общие результаты тестирования

Тип

AVG CPU (%)

AVG RAM (mb)

AVG RPS

Результат yandex tank

Swoole

45

752

152.5

https://clck.ru/3DbnXQ

FrankenPHP

68

954

140.7

https://clck.ru/3DbqLi

RoadRunner

60

638

131.5

https://clck.ru/3DbpkP

Nginx Unit

87

2384

39.1

https://clck.ru/3DbpLp

Apache+mod_php

89

5277

37.5

https://clck.ru/3DboQw

PHP-FPM

87

3500

37.3

https://clck.ru/3Dbnig





Нагрузка на CPU


График использование памяти

График времени ответа сервера

Для более корректного сравнения серверов стоит разделить их на две группы:

  • Сервера, которые инициализируют приложение при каждом запросе: Apache mod_php, PHP-FPM, Nginx Unit.

  • Сервера с долгоживущими процессами, которые загружают приложение один раз и продолжают с ним работать: FrankenPHP, Swoole, RoadRunner.

В первой группе (Apache mod_php, PHP-FPM, Nginx Unit) разница в RPS незначительна. Однако PHP-FPM и Nginx Unit более эффективны в плане использования ресурсов. 

В тестах часто сравнивают PHP-FPM и mod_php, используя статичные данные (например, вывод phpinfo). В таких случаях PHP-FPM действительно демонстрирует прирост производительности в 300%+, что актуально только для статичных данных.

Примеры тестирования вывода phpinfo:

Время ответа от сервера в случае с Apache возрастает до 8 сек. В то время как PHP-FPM стабильно отдает страницы за 200-300 мс.

Результат тестирования phpinfo с Apache+mod_php


Результат тестирования phpinfo с PHP-FPM

Тестирование сложных приложений, таких как Bagisto, показывает, что при динамических нагрузках разница между PHP-FPM и mod_php минимальна.

Во второй группе (FrankenPHP, Swoole, RoadRunner) — долгоживущие процессы. Они обеспечивают существенное снижение потребления ресурсов и значительный прирост RPS по сравнению с первой группой. Однако важно учитывать, что приложение должно быть адаптировано для работы с серверами, которые загружаются в память один раз и продолжают функционировать без повторной инициализации.

Сообщество и поддержка

Приложения, такие как Swoole, RoadRunner, FrankenPHP и Nginx Unit, пользуются активной поддержкой сообщества разработчиков. Давайте сравним уровень этой поддержки.

Сервер 

Количество звезд

Количество мейнтейнеров

Количество релизов (за год)

Количество созданных issue (за год)

Процент закрытых issue

Swoole

18.4k

151

5

207

95

RoadRunner

7.9k

53

20

112

74

FrankenPHP

6.8k

83

20

366

73

Nginx Unit

5.4k

46

7

236

61


Выводы

  • Apache mod_php лучше использовать вместе с Nginx в качестве сервера для статики в проектах где нет серьезных нагрузок и ничего не хочется конфигурировать.

  • PHP-FPM оптимален для большинства стандартных и даже высоконагруженных проектов благодаря широкому использованию и активной поддержке сообщества. 

  • NGINX Unit обеспечивает производительность, близкую к PHP-FPM, но обладает дополнительными преимуществами — поддержка нескольких языков и возможность запуска нескольких серверов, что делает его отличным выбором для микросервисных архитектур.

Swoole, FrankenPHP и RoadRunner хорошо подходят для высоконагруженных и асинхронных приложений, позволяя использовать долгоживущие процессы и снижая накладные расходы на инициализацию приложения. Однако такие решения требуют, чтобы приложение было адаптировано к работе с долгоживущими процессами. Из трех решений Swoole выделяется как наиболее популярное в сообществе и демонстрирует лучшую производительность и более низкое потребление ресурсов в наших тестах.

Оцените статью
14.11.2024
Понравилась статья?
Поделитесь ссылкой с друзьями и коллегами!

Статьи по теме

Организация поиска на сайте: выбираем между поиском Битрикса, Sphinx и ElasticsearchВ статье разбираем популярные поисковые движки, чтобы выбрать лучший под задачи конкретного проекта. Даем советы по индексации каталога и построении «умного» фи...
Доработка системы LMS KnomaryMust have для бизнеса, где главный актив это люди, — стратегия обучения и развития персонала. Рассказываем как помогли доработать LMS-систему для компании ЕВРАЗ...
«Как раньше» больше не работает — B2B-система продаж сейчасВ этой статье хотим поговорить с чем сейчас сталкивается оптовый бизнес (множеством вызовов и изменений, которые требуют адаптации, а также оптимизации процессо...
Интеграция B2B-платформы на Битрикс с системой авторизации KeycloakВ период бурного роста компании менеджмент учетных записей сотрудников и клиентов может стать проблемой. Решение — интеграция с брокером авторизаций Keycloak ил...
Разработка календаря бронирования для сайта на Битрикс авиационного учебного центраЧтобы пилоты авиакомпаний могли бронировать время своих тренировок в учебном центре, мы разработали для них удобный модуль бронирования времени. Рассказываем по...
Мы работаем по одному из двух форматов:
  • аренда команды (от 2 человек, не менее 3 месяцев);
  • итерации с фиксированной ценой (1-3 месяца длительностью).
ИНТЕРВОЛГА предоставляет:
  • регулярные онлайн-планерки с заказчиком;
  • квалифицированных специалистов;
  • организованную команду (находятся в одном помещении, что упрощает решение рабочих вопросов);
  • полную прозрачность и регулярность отчетов о результатах.
Ключевые услуги:
  • нагруженный интернет-магазин;
  • личный кабинет;
  • оптовые продажи — B2B-платформа;
  • маркетплейс;
  • технический аудит сайта;
  • Битрикс24 — корпоративные HR-порталы;
  • Битрикс24 — построение CRM-системы;
  • Битрикс24 — личные кабинеты сотрудников;
  • Битрикс24 — аудит портала;
  • 1С — интеграция с другими системами;
  • 1С — доработка системы;
  • маркетинг — комплексное интернет-продвижение;
  • маркетинг — продвижение для B2B.
Хотите получать лучшие статьи от INTERVOLGA раз в месяц?
Подпишитесь на рассылку — спамить не будем