Принцип мягкой перезагрузки
Что такое мягкая перезагрузка?
Мягкая перезагрузка отличается от обычной перезагрузки тем, что она позволяет перезапустить сервис (обычно имеет в виду бизнес с короткими соединениями) без воздействия на пользователей, для того чтобы перезагрузить PHP программу и завершить обновление бизнес-кода.
Мягкая перезагрузка обычно применяется в процессе обновления бизнеса или выпуска версии, что позволяет избежать временной недоступности сервиса из-за перезагрузки при публикации кода.
Внимание
Windows система не поддерживает reload.Внимание
При работе с длинными соединениями (например, websocket) подключения будут разорваны во время мягкой перезагрузки процессов. Решением является использование архитектуры, подобной gatewayWorker, где группа процессов специально поддерживает соединения и у этой группы процессов устанавливается reloadable атрибут в false. Логика бизнеса запускает другую группу worker процессов для обработки, gateway и worker процессы вызывают друг друга через tcp-соединение. Когда нужно изменить бизнес, необходимо перезапустить только worker процессы.
Ограничения
Внимание: только файлы, загруженные внутри колбэков on{...}, будут автоматически обновлены при мягкой перезагрузке; файлы, загруженные напрямую в скрипте запуска, или закодированные в коде, не будут автоматически обновлены при вызове reload.
Следующий код не будет обновлен после reload
$worker = new Worker('http://0.0.0.0:1234');
$worker->onMessage = function($connection, $request) {
$connection->send('hi'); // Закодированный код не поддерживает горячее обновление
};
$worker = new Worker('http://0.0.0.0:1234');
require_once __DIR__ . '/your/path/MessageHandler.php'; // Файл, загруженный напрямую в скрипте запуска, не поддерживает горячее обновление
$messageHandler = new MessageHandler();
$worker->onMessage = [$messageHandler, 'onMessage']; // Предположим, что в классе MessageHandler есть метод onMessage
Следующий код будет автоматически обновлен после reload
$worker = new Worker('http://0.0.0.0:1234');
$worker->onWorkerStart = function($worker) { // onWorkerStart - это колбэк, который срабатывает после запуска процесса
require_once __DIR__ . '/your/path/MessageHandler.php'; // Файлы, загруженные после запуска процесса, поддерживают горячее обновление
$messageHandler = new MessageHandler();
$worker->onMessage = [$messageHandler, 'onMessage'];
};
После изменения MessageHandler.php выполните php start.php reload, и MessageHandler.php будет перезагружен в память, чтобы обновить бизнес-логику.
Подсказка
Приведённый выше код для удобства демонстрации используетrequire_once; если ваш проект поддерживает автозагрузку psr4, то вызватьrequire_onceне нужно.
Принцип мягкой перезагрузки
Workerman делится на главный процесс и дочерние процессы, главный процесс отвечает за мониторинг дочерних процессов, а дочерние процессы занимаются приемом подключений от клиентов и обработкой полученных запросов, возвращая данные клиенту. Когда код бизнеса обновляется, на самом деле нам нужно обновить только дочерние процессы, чтобы достичь цели обновления кода.
Когда главный процесс Workerman получает сигнал мягкой перезагрузки, он отправляет сигнал безопасного выхода (чтобы соответствующий процесс завершил обработку текущего запроса перед выходом) одному из дочерних процессов. После выхода этого процесса главный процесс заново создает новый дочерний процесс (этот дочерний процесс загружает новый PHP код), затем главный процесс снова отправляет команду остановки другому старому процессу, таким образом происходит поочередная перезагрузка процессов, пока все старые процессы не будут заменены.
Мы видим, что мягкая перезагрузка фактически осуществляется за счет поочередного выхода старых бизнес-процессов и создания новых процессов. Чтобы не повредить пользователю во время мягкой перезагрузки, требуется не сохранять информацию о состоянии, относящуюся к пользователям, в процессе, то есть желательно, чтобы бизнес-процесс был без состояния, чтобы избежать потери информации из-за выхода процесса.