Princípio do Reinício Suave

O que é Reinício Suave?

O reinício suave difere do reinício comum; ele permite reiniciar o serviço (geralmente referindo-se a serviços de conexões curtas) sem impactar os usuários, a fim de recarregar o programa PHP e completar a atualização do código do negócio.

O reinício suave é geralmente aplicado durante o processo de atualização ou lançamento de versões, podendo evitar a indisponibilidade temporária do serviço causada pela reinicialização do serviço durante a publicação de código.

Atenção
O sistema Windows não suporta reload.

Atenção
Para serviços de conexões longas (como WebSocket), as conexões serão desconectadas durante o reinício suave do processo. A solução é usar uma arquitetura semelhante ao gatewayWorker, onde um grupo de processos é dedicado à manutenção das conexões, e a propriedade reloadable desse grupo de processos deve ser definida como false. A lógica do negócio deve iniciar um outro grupo de processos worker para processar, e o gateway e os processos worker se comunicam mutuamente via tcp. Quando a lógica do negócio precisa ser alterada, apenas os processos worker precisam ser reiniciados.

Restrições

Atenção: Apenas os arquivos carregados dentro do callback on{...} serão atualizados automaticamente após um reinício suave; arquivos carregados diretamente no script de inicialização ou código fixo não serão atualizados automaticamente ao executar reload.

O seguinte código não será atualizado após reload

$worker = new Worker('http://0.0.0.0:1234');
$worker->onMessage = function($connection, $request) {
    $connection->send('hi'); // Código fixo não suporta atualização quente
};
$worker = new Worker('http://0.0.0.0:1234');
require_once __DIR__ . '/your/path/MessageHandler.php'; // Arquivos carregados diretamente pelo script de inicialização não suportam atualização quente
$messageHandler = new MessageHandler();
$worker->onMessage = [$messageHandler, 'onMessage']; // Assume que a classe MessageHandler possui um método onMessage

O seguinte código será atualizado automaticamente após reload

$worker = new Worker('http://0.0.0.0:1234');
$worker->onWorkerStart = function($worker) { // onWorkerStart é o callback chamado após o processo ser iniciado
    require_once __DIR__ . '/your/path/MessageHandler.php'; // Arquivos carregados após o início do processo suportam atualização quente
    $messageHandler = new MessageHandler();
    $worker->onMessage = [$messageHandler, 'onMessage'];
};

Após modificar MessageHandler.php, execute php start.php reload e MessageHandler.php será recarregado na memória, atingindo o efeito de atualização da lógica de negócio.

Dica
O código acima usa a instrução require_once para facilitar a demonstração; se seu projeto suporta carregamento automático psr4, não é necessário chamar a instrução require_once.

Princípio do Reinício Suave

O Workerman é dividido em um processo principal e processos filhos. O processo principal é responsável por monitorar os processos filhos, enquanto os processos filhos são responsáveis por receber as conexões dos clientes e os dados de solicitação enviados através dessas conexões, processando-as e retornando os dados ao cliente. Quando o código do negócio é atualizado, na verdade, só precisamos atualizar os processos filhos para conseguir atualizar o código.

Quando o processo principal do Workerman recebe um sinal de reinício suave, ele envia um sinal de saída segura (permitindo que o processo correspondente conclua a solicitação atual antes de sair) para um dos processos filhos. Quando esse processo sai, o processo principal irá recriar um novo processo filho (este novo processo carrega o novo código PHP), e então o processo principal enviará um comando de parada para outro processo antigo. Assim, um processo de cada vez é reiniciado até que todos os processos antigos sejam substituídos.

Podemos ver que o reinício suave é, na verdade, um processo de saída gradual dos processos antigos de negócios, seguido pela criação gradual de novos processos. Para que o reinício suave não impacte os usuários, é necessário que os processos não mantenham informações de estado relacionadas ao usuário, ou seja, os processos de negócio devem ser sem estado, evitando a perda de informações devido à saída do processo.