關於swoole服務的重啓方式
一、程序內的自重啓
1、$server->reload
安全地重啓所有Worker/Task
進程,確保正在執行的任務執行完成後才重啓,master/manager
進程不會停止。
bool Server->reload(bool $only_reload_taskworkrer = false)
$only_reload_taskworkrer 是否僅重啓Task進程。
reload有保護機制,當一次reload正在進行時,收到新的重啓信號會丟棄。
如果設置了user/group,Worker進程可能沒有權限向Master進程發送信息,這種情況下必須使用root賬戶,在shell中執行kill指令進行重啓
reload指令對addProcess添加的用戶進程無效。
注意:平滑重啓只對 onWorkerStart 或 onReceive 等在 Worker 進程中 include / require 的PHP文件有效,Server啓動前就已經 include / require 的PHP文件,不能通過平滑重啓重新加載。
對於Server的配置即$serv->set()中傳入的參數設置,必須關閉/重啓整個Server纔可以重新加載。這就要求你能判斷出,你修改的文件是在哪裏被引入的,task / worker / master。
2、$server->stop()
停止Worker進程。默認是停止當前Worker進程。
3、$server->shutdown()
關閉服務器。
可在Worker進程內調用來關閉服務器,如果Worker進程內發生致命錯誤或者邏輯錯誤時可這樣做。
客戶端的連接是否會保持,取決於服務的運行模式:
SWOOLE_PROCESS
:來自客戶端的連接是由master進程管理,worker進程的重啓和異常退出,不會影響連接本身。
SWOOLE_BASE
:客戶端連接直接維持在Worker進程中,因此reload時會切斷所有連接。並且Base模式不支持reload Task進程。
二、外部重啓程序
1、Server可以監聽一個內網端口,然後可以接收遠程的控制命令。
2、向進程發送指令。
比如,./server stop | restart | reload | status
等。一般我們在更新代碼後需要restart/reload。
實現方式是,在啓動服務後,將master和manager進程id保存到文件pid_file。然後使用
\Swoole\Process::kill($pid, $signo = SIGTERM)
方法來向master / manager進程發送信號。
信號:
0:可以檢測進程是否存在,不會發送信號。
SIGTERM: 向主進程/管理進程發送此信號服務器將安全終止。
SIGUSR1: 向主進程/管理進程發送SIGUSR1信號,將平穩地重啓所有Worker進程。
SIGUSR2: 向主進程/管理進程發送SIGUSR2信號,將平穩地重啓所有Task進程。
SIGKILL:強制殺死進程,類似於 kill -9 xxx 。適用於 強制停止/強制重啓 服務。
status
1、判斷 pid_file 中是否保存了masterPid, managerPid。
2、然後判斷managerPid是否存在,\Swoole\Process::kill(managerPid, 0)。
因爲manager進程存在,則master進程也存在。
stop
1、先判斷status。
2、如果是強制關閉服務,使用kill -9 masterPid 或者 \Swoole\Process::kill(masterPid, SIGKILL)。
3、如果是平滑關閉服務:\Swoole\Process::kill(masterPid, SIGTERM);
此種方式會等待任務處理完才關閉服務,因此需要while循環來判斷masterPid是否
存在 \Swoole\Process::kill(masterPid, 0) 直到master進程不存在才說明停止成功了。
4、然後刪除pid_file文件。
reload平滑重啓
先判斷status。
向managerPid發送 SIGUSR1 指令:\Swoole\Process::kill(managerPid, SIGUSR1)。
restart重啓
先判斷status。
調用stop指令。
調用start指令。