背景
对于无关紧要的进程,我们可以随时kill掉再重启,但是有时候不能这样粗暴地操作。
假设我们正在处理一个从消息系统得到的消息,而消息是 非持久化/自动ack 的,如果进程被打断,这条消息就可能丢失。
或者我们在处理一个耗时特别长的任务,这时别人不小心kill掉了我们的进程,那我们前面的成果就付诸东流了。
针对上面这些情况,我们在Api进程里加入了平滑关闭的特性,你可以捕获进程关闭指令,自己决定何时关闭。
下面是一些使用方法:
使用
使用方法一:闭包
class Cront extends MY_Controller
{
public function run()
{
$ready_exit = false;
$this->regSig(SIGTERM, function() use (&$ready_exit) {
$ready_exit = true;
echo "准备退出!";
});
while (true) {
{
/**
* 括号里是业务处理代码
*/
echo "正在处理业务...\n";
sleep(3);
echo "业务处理完毕!\n";
}
$this->catchSig();
if ($ready_exit) {
echo "exit now!\n";
exit;
}
}
}
}
使用方法二:对象方法
class Cront extends MY_Controller
{
public $ready_exit = false;
public function handSig($sig, $my_var1, $my_var2)
{
switch ($my_var1) {
case 'run':
$this->ready_exit = true;
echo "exit ready\n";
break;
}
var_dump(func_get_args());
}
public function run()
{
$this->regSig(SIGTERM, array($this, 'handSig'), 'run', 'myvar');
while (true) {
{
/**
* 括号里是业务处理代码
*/
echo "正在处理业务...\n";
sleep(3);
echo "业务处理完毕!\n";
}
$this->catchSig();
if ($this->ready_exit) {
echo "exit now!\n";
exit;
}
}
}
}
注意
- 进程捕获关闭指令后,用 kill -9 仍然可以杀死进程;
- api里的 regSig 不仅可以捕获 SIGTERM 信号,还可以捕获其他信号;
- 如果调用了 regSig 而没有调用 catchSig ,程序仍然捕获不到信号;
- 不用 declare(ticks = 1); 是考虑到性能;