Читая PHP-дайджест, мы в Evapps наткнулись на интересную новость — вовсю идёт голосование по [RFC] Fibers. В двух словах — это попытки внести немного асинхронности в монолитно-синхронное до сих пор выполнение PHP-кода. А там, глядишь, и до многозадачности недалеко. Но это пока лишь мечты. А в реальности, как оказалось, существует сервис, который УЖЕ создал многопоточность в PHP. Называется он Swoole. Кстати, в новом пакете Laravel — Laravel Octane — под капотом будет использоваться именно этот сервис, Swoole. Об этом рассказал создатель Laravel Тейлор во время презентации пакета.

Рассказывать о Swoole с нуля кажется бессмысленным, так как уже есть люди, которые не просто покрутили сервис на тестовом сервере, но и перевели на него свой проект, получили отличный результат, о котором и отчитались. Хотим с вами поделиться этим отчётом. Представляем перевод статьи основателя компании Appwrite Элдада Фукса Moving From Nginx+FPM to Swoole Has Increased Our PHP API Performance by 91%.


В прошлом месяце мы выпустили Appwrite 0.7 со множеством новых функций. Одно из главных нововведений — мы перешли со стека Nginx + PHP FPM на использование Swoole в качестве HTTP-сервера.

В Appwrite мы создаем бесплатную альтернативу Google Firebase — платформу с открытым исходным кодом, которую можно разместить самостоятельно в любой инфраструктуре. Наш стек состоит из набора контейнеров Docker, использующих архитектуру микросервисов, что позволяет быстро масштабировать и отлаживать отдельные компоненты, составляющие серверный API. Наш backend API является хорошей отправной точкой для создания новых веб-проектов, мобильных проектов или проектов Flutter. Продукт «?из коробки» предлагает готовые к использованию модули аутентификации (Auth), хранилище (Storage), базы данных (Database), облачные функции (Cloud Functions) и другие стандартные API-интерфейсы, которые требуются любому приложению, занимающемуся обработкой данных пользователей и разрешений.

Как мы используем Swoole

Swoole — это высокопроизводительные, масштабируемые, параллельные TCP, UDP, Unix Socket, HTTP, WebSocket сервисы с PHP и простым в использовании Coroutine fiber API. Используя Swoole, мы имеем всего один многопоточный процесс, запущенный на нашем HTTP-сервере, что позволяет обработчику HTTP-запроса разделять память между несколькими пользователями. С таким подходом мы можем поддерживать постоянные соединения с БД и избегать повторной инициализации приложения с нуля для каждого пользователя, что помогает эффективнее использовать память и процессор.

Кроме того, Swoole дает возможность использовать корутины (Coroutine). Корутины Swoole подобны корутинам в других языках или фреймворках. Swoole создаёт по одной корутине на каждый запрос и выполняет их, основываясь на IO статусе каждого запроса. Swoole идёт со встроенными асинхронными клиентами Redis, MySQL, Postgres, позволяя повысить производительность.

Использование Swoole в качестве веб-сервера отлично подходит при разработке системы для работы в архитектуре микросервисов, подобной нашей. Вместо того, чтобы иметь один контейнер с Supervisord для управления всеми процессами Nginx, FPM и PHP, работающими в фоновом режиме, каждый из наших контейнеров Docker имеет один-единственный процесс в качестве точки входа, который намного проще масштабировать, отлаживать и отслеживать. Вы можете использовать Nginx и PHP в отдельных контейнерах, но они не являются нативными для Docker, и такое их использование ведёт к дополнительным накладным расходам.

Benchmarks

Чтобы оценить улучшения, мы протестировали различные сценарии в версиях 0.6.2 и 0.7.0. Мы выполняли запросы к нескольким конечным точкам (точкам входа, endpoints) с запросами на чтение и на запись. Все запросы были направлены на конечные точки, которым требуется аутентификация и контроль за злоупотреблениями, то есть на функции, которые выигрывают от этих улучшений.

Оба теста выполнялись на одном и том же оборудовании и не были направлены на то, чтобы продемонстрировать максимальную производительность Swoole. Цель тестирования заключалась в том, чтобы сравнить работу новой и старой версий. Результаты ниже относятся к 5-минутному нагрузочному и стресс-тестированию с 500 одновременными клиентами, использующими K6.

Версия 0.6.2

Результаты тестов Appwrite 0.6
Результаты тестов Appwrite 0.6

Как видно на скриншоте, только 98% всех запросов были успешными. Остальные закончились тайм-аутом из-за перегрузки.

Версия 0.7

Результаты тестов Appwrite 0.7
Результаты тестов Appwrite 0.7

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

Результаты

С учетом всех факторов полученные результаты означают, что производительность увеличилась примерно на 91%. Благодаря Swoole наш стек стал намного быстрее и проще в обслуживании. Фактически онлайн-тесты показывают, что Swoole + PHP с легкостью опережает популярные альтернативы Node.js и Python и не сильно отстает от компилируемых языков, таких как GO.

Такое повышение производительности — часть действий, которые мы предпринимаем, чтобы дать разработчикам возможность в полной мере использовать свои серверы на основе Appwrite. Мы предоставим больше информации о процессе разработки и тестах Appwrite при запуске новых версий.

Мы благодарим команду Swoole за поддержку и помощь в процессе миграции, который был на удивление простым и быстрым. Буквально за пару дней мы добрались до первой рабочей версии всего нашего API.

Что дальше?

Если вы заинтересовались Appwrite (https://appwrite.io), ознакомьтесь с руководствами по началу работы для Web, Flutter или Server, а также присоединяйтесь к нашему сообществу Discord, где мы обсуждаем Appwrite с более чем 1300 соавторами платформы.

Также вы можете посетить наши проекты на Github, запросить новые функции в Github issues и ознакомиться с будущими спецификациями функций в репозитории Appwrite RFCs.