부드러운 재시작 원리

부드러운 재시작이란 무엇인가?

부드러운 재시작은 일반적인 재시작과 다릅니다. 부드러운 재시작은 서비스에 영향을 주지 않으면서 서비스(일반적으로는 단기 연결 비즈니스)를 재시작할 수 있게 해 주며, PHP 프로그램을 다시 로드하고 비즈니스 코드를 업데이트할 수 있게 해 줍니다.

부드러운 재시작은 일반적으로 비즈니스 업데이트나 버전 배포 과정에서 사용되며, 코드 배포로 인한 서비스 불가의 일시적인 영향을 피할 수 있습니다.

주의
Windows 시스템은 reload를 지원하지 않습니다.

주의
장기 연결(예: websocket) 비즈니스의 경우, 프로세스가 부드럽게 재시작될 때 연결이 끊어질 수 있습니다. 해결方案은 gatewayWorker와 같은 아키텍처를 사용하여 연결을 유지하는 프로세스 그룹을 만들고 이 프로세스 그룹의 reloadable 속성을 false로 설정하는 것입니다. 비즈니스 로직은 다른 워커 프로세스 그룹을 시작하여 처리하며, gateway와 worker 프로세스는 TCP 통신 방식으로 서로 호출합니다. 비즈니스 변경이 필요한 경우 워커 프로세스만 재시작하면 됩니다.

제한 사항

주의: 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 코드를 로드함). 그런 다음 마스터 프로세스는 이전의 다른 프로세스에 중지 명령을 다시 보냅니다. 이렇게 하나씩 프로세스를 재시작하여 모든 이전 프로세스가 교체될 때까지 진행됩니다.

부드러운 재시작은 실제로 이전 비즈니스 프로세스가 하나씩 종료된 후 하나씩 새로운 프로세스를 생성하는 방식으로 이루어집니다. 부드러운 재시작 중에 고객에게 영향을 주지 않기 위해, 프로세스가 사용자 관련 상태 정보를 저장하지 않도록 해야 하며, 즉 비즈니스 프로세스는 무상태여야 하며 프로세스 종료로 인한 정보 손실을 피해야 합니다.