Skip to content

Режимы выполнения ​

Пул HTTP запускает PHP в одном из трёх режимов выполнения. Пул gRPC использует режим Dispatcher.

РежимОписание
ClassicВходной скрипт каждый раз выполняется в новом PHP-запросе, как под php-fpm.
WorkerРезидентный скрипт обрабатывает запросы в цикле. Rapira заново заполняет суперглобальные переменные для каждого запроса.
DispatcherВоркер получает каждый запрос вызовом API и использует объект запроса вместо суперглобальных переменных.

Названия режимов - это значения http.pool.mode и варианты перечисления Rapira\Mode. Classic удаляет состояние запроса приложения после каждого запроса. Worker и Dispatcher сохраняют одно инициализированное приложение для многих запросов. Состояние приложения и его зависимости от API определяют, какие режимы может использовать приложение.

Classic ​

Входной скрипт каждый раз выполняется в новом PHP-запросе, как в php-fpm. Rapira заполняет суперглобальные переменные, выполняет скрипт, отправляет ответ и затем удаляет состояние запроса. Постоянные соединения и состояние расширений остаются, потому что они находятся в процессе воркера.

Существующее приложение может работать без изменения кода, когда Rapira заменяет php-fpm. Rapira встраивает PHP в процесс сервера и не использует FastCGI.

Подробности - в разделе Режим Classic.

Worker ​

Режим Worker использует те же интерфейсы запросов и ответов, что и Classic. Приложение читает суперглобальные переменные и может использовать echo для ответа. Скрипт воркера один раз инициализирует приложение, а затем запускает цикл. Для каждого запроса Rapira заново заполняет суперглобальные переменные и вызывает обработчик. Объекты, которые скрипт создаёт за пределами цикла, остаются доступными.

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

Скрипт воркера и его цикл описаны в разделе Режим Worker. Обработка запросов и ответов описана в разделе HTTP.

Dispatcher ​

В режиме Dispatcher скрипт воркера получает каждую единицу работы вызовом API. Rapira\get_dispatcher() возвращает диспетчер пула, а его метод receive() ожидает следующую единицу. В HTTP-плагине каждая единица - это Rapira\Http\Exchange. Exchange даёт объект Rapira\Http\Request и содержит методы, которые записывают ответ. В плагине gRPC каждая единица - это Rapira\Grpc\UnaryCall.

Приложение может передавать объект запроса функциям или middleware. Rapira не заполняет суперглобальные переменные в этом режиме. Приложению, которое читает суперглобальные переменные, нужен режим Worker или адаптер, который копирует данные запроса в эти переменные. echo и другой вывод PHP не попадают к клиенту. Rapira пишет этот вывод в лог с целью php на уровне info.

Каждый воркер обрабатывает одну единицу работы за раз. Завершите текущую единицу до следующего вызова receive(). Чтобы обрабатывать больше запросов одновременно, увеличьте http.pool.processes.

Цикл, API запроса и ответа и исключения описаны в разделе Режим Dispatcher. API вызовов gRPC описан в разделе gRPC.

$_SERVER до первого запроса ​

В режимах Worker и Dispatcher входной скрипт запускается до первого запроса. В этот момент Rapira заполняет $_SERVER так же, как PHP CLI для php entrypoint.php.

КлючЗначение
Каждая переменная окружения процессаЗначение из окружения
PHP_SELF, SCRIPT_NAME, SCRIPT_FILENAME, PATH_TRANSLATEDАбсолютный путь входного скрипта
DOCUMENT_ROOTПустая строка
REQUEST_TIME, REQUEST_TIME_FLOATВремя запуска входного скрипта
argvСписок, который содержит абсолютный путь входного скрипта
argc1

$_SERVER получает переменные окружения, если variables_order содержит S. $_ENV получает их, только если variables_order содержит E. Значение для продакшена GPCS не содержит E. Путь входного скрипта заменяет переменную окружения с тем же именем, например SCRIPT_FILENAME. Глобальные переменные $argv и $argc содержат те же значения, что и $_SERVER.

В режиме Dispatcher $_SERVER сохраняет эти значения до следующего запуска входного скрипта. Данные запроса находятся в объекте запроса. В режиме Worker Rapira заново заполняет $_SERVER данными запроса для каждого запроса. Значения запроса не содержат переменных окружения, а SCRIPT_NAME содержит имя входного скрипта с начальным слешем.

Чтение режима во время работы ​

Rapira\get_mode() возвращает режим процесса как вариант Rapira\Mode. Варианты: Classic, Worker и Dispatcher. Вариант равен режиму пула воркера и не меняется, пока процесс работает. Функция не принимает аргументы и не бросает исключения. Входной скрипт может использовать её для поддержки нескольких режимов.

php
<?php
// entry.php

use Rapira\Mode;

$app = require __DIR__ . '/bootstrap.php';

match (\Rapira\get_mode()) {
    Mode::Classic => $app->handleOnce(),
    Mode::Worker => $app->runWorkerLoop(),
    Mode::Dispatcher => $app->runDispatcherLoop(),
};
Почему режим не меняется, пока процесс работает?

Rapira читает режим пула до запуска интерпретатора. Каждый запрос в этом воркере возвращает один и тот же вариант. Перезагрузка не читает rapira.toml заново. Чтобы изменить режим, перезапустите Rapira.

Выбор режима ​

Ключ mode таблицы пула выбирает режим. Значение по умолчанию - dispatcher. Задайте режим явно в rapira.toml.

toml
[http]
listen = "127.0.0.1:8000"

[http.pool]
entrypoint = "public/index.php"
mode = "classic"                      # Use "classic", "worker", or "dispatcher". Default: "dispatcher".
sh
rapira serve rapira.toml

Пул HTTP поддерживает все три режима. Пул gRPC поддерживает только dispatcher. Другое значение grpc.pool.mode останавливает Rapira при запуске с ошибкой.

В режимах Worker и Dispatcher входной скрипт должен получать запросы в цикле. Если скрипт завершается до получения запроса, инициализация завершается сбоем. Обычный входной скрипт для php-fpm завершается так в режиме по умолчанию. Действия Rapira после сбоя инициализации описаны в разделе Модель процессов.

Код и зависимости приложения могут ограничить выбор. Используйте Classic, если глобальное состояние не может сохраняться между запросами. Код, который читает суперглобальные переменные, не может использовать Dispatcher без адаптера. Некоторые интеграции фреймворков поддерживают режим Worker. Документированные интеграции описаны в разделе Фреймворки.

Режим применяется ко всему пулу, поэтому все маршруты в этом пуле используют один режим. Пулы HTTP и gRPC могут использовать разные режимы в одном сервере. Запустите несовместимые HTTP-маршруты в отдельном экземпляре Rapira в режиме Classic. Дополнительная информация находится в разделах Конфигурация и Командная строка.

Начните с Classic при замене php-fpm. Проверьте работу приложения. Выберите Worker после подтверждения, что приложение правильно инициализируется и не сохраняет состояние запроса.