版权声明:转载请注明来源 https://blog.csdn.net/u013702678/article/details/82710676
通过前面两篇文章分析了provider_admin里面服务启动过程,这篇我们把剩下的几个操作的实现做介绍,这里主要介绍stop,reload这两个操作,其他的动作status,list,restart等,不展开具体分析。先介绍stop过程。
//停止单个应用
function stopProvider($name)
{
//获取应用master进程ID
$masterPid = getProviderMasterPid($name);
if (empty($masterPid))//进程ID为空
{
waitProcessEnd($name);//等待应用的master和manager进程结束
}
else //成功获取到master进程ID
{
//向master进程发送SIGTERM信号中断master进程
if (!posix_kill(intval($masterPid), SIGTERM))
{
fwrite(STDERR, "end signal to {$name}: {$masterPid} failed" );
}
waitProcessEnd($name);//等待应用的master和manager进程结束
}
//记录应用master进程ID的文件路径
$masterFile = FSOF_PROVIDER_PID_PATH.$name.MASTER_PID_FILE_FORMAT;
//记录应用manager进程的ID文件路径
$managerFile = FSOF_PROVIDER_PID_PATH.$name.MANAGER_PID_FILE_FORMAT;
if (file_exists($masterFile))//文件存在
{
unlink($masterFile);//php API函数,删除文件
}
if (file_exists($managerFile))//文件存在
{
unlink($managerFile);//php API函数,删除文件
}
echo "stop server {$name} \033[32;40m [SUCCESS] \033[0m".PHP_EOL;
}
function waitProcessEnd($name)
{
/*
* 先检测该master进程是否存在,检测时间为10s,不存在则退出,如一直存在,则强制杀掉子进程(发送SIGKILL信号),目的为了manager进程能正常退出, 从zookeeper注销服务
* ,等待2s后重新检测,如仍存在,则强制杀除master与manager进程
*/
$work_name= "{$name}_event_worker_process";
$stime = time();
while(time() - $stime < 10)
{
//获取master进程的进程ID
$pid = getProviderMasterPid($name);
if (empty($pid))//进程ID为空,也就是进程不存在时,退出循环
{
break;
}
sleep(1);//让出CPU,防止CPU短期飙升
}
//获取所有worker进程的进程ID信息,一般worker进程都会有多个,如果master进程正常退出,worker进程也会退出的,这里防止异常情况worker进程没退出
$workPid = trim(filterProcess($work_name, PS_CMD_WORK_PROCESS));
if (!empty($workPid))//worker进程集合不为空
{
$pids = explode("\n", $workPid);
foreach ($pids as $key => $wPid)
{
posix_kill(intval($wPid), SIGKILL);//发送SIGKILL信号杀掉worker进程
usleep(10000);
}
}
//强制退出master进程和manager进程,通过kill命令强制结束
sleep(1);
$pid = getProviderMasterPid($name);
if (!empty($pid))
{
$managerPid = getProviderManagerPid($name);//获取manager进程ID信息
if(!empty($managerPid))
{
posix_kill(intval($managerPid), SIGKILL);//向manager进程发送kill信号
}
posix_kill(intval($pid), SIGKILL);
}
}
下面开始分析reload过程,reload一般表示平滑重启。
function reloadProvider($name)
{
$pid = getProviderMasterPid($name);//获取master进程ID信息
if (!posix_kill(intval($pid), SIGUSR1))//发送自定义的信号SIGUSR1,swoole对于这个信号会平滑重启
{
echo $name."server {$name} reload \033[31;40m [FAIL] \033[0m".PHP_EOL;
}
else
{
fwrite(STDERR, "server {$name} reload \033[32;40m [SUCCESS] \033[0m".PHP_EOL);
}
}