美文网首页
pcntl信号机制配合swoole进程池 不影响业务平滑重启子进

pcntl信号机制配合swoole进程池 不影响业务平滑重启子进

作者: 骑蚂蚁上高速_jun | 来源:发表于2020-03-05 08:33 被阅读0次

场景:
由于公司的邮件Smtp服务器,是基于swoole的进程池实现的。但是swoole进程池,并没有平滑重启功能,如果当你的业务还在worker中运行的时候,通过 SIGUSR1 或 SIGUSR2 信号重新启动所有的worker,这样会导致你的部分业务丢失。

解决方案:
swoole进程池 的底层仅设置了主进程(管理进程)的信号处理,并未对 Worker 工作进程设置信号,如果你在worker中进行了
信号监听,那么就可以实现worker 进程的平滑重启

*   工作进程为异步模式,请使用 [Swoole\Process::signal](https://wiki.swoole.com/#/process?id=signal) 监听信号
*   工作进程为同步模式,请使用 `pcntl_signal` 和 `pcntl_signal_dispatch` 监听信号

由于swoole的进程池是同步模式,故采用 pcntl_signal
$pool->on("WorkerStart", function (Pool $pool,int $workerId) {
    swoole_set_process_name("mail:pool:{$workerId}"); // 设置进程别名
    $redis = new Redis();
    $redis->connect("127.0.0.1");
    $redis->setOption(Redis::OPT_READ_TIMEOUT,-1);
    $run=true;

/**
* 安装信号,便于调用
* 不会主动执行,由信号触发器 触发执行
* 发送 USR1 信号 会重启进程
* 发送 TERM 信号 会停止信号
*/
    pcntl_signal(SIGTERM, function ($signo) use(&$run,$pool){
        echo "pcntl收到 {$signo} 信号\n";
        $run=false;
    });
    echo "进入redis->{$workerId}\n";
    while($run){
        if($redis->ping() != "+PONG"){
            $redis = new redis;
            $redis->connect("127.0.0.1");
            $redis->setOption(redis::OPT_READ_TIMEOUT,-1);
        }

        $data = $redis->brPop("list:swoole",3);
/***
* 等待外部信号,并且调用信号。该函数有两个功能。
1 . 等待外部信号调用。2.触发信号。
备注: 该函数只有接收到外部信号时,才能触发信号
*/
        pcntl_signal_dispatch();
        $datas = $data[1] ?? "";
        if($datas){
            require "/data/wwwroot/php-cli/beanstalk.php";
            co::sleep(20); // 代替业务逻辑等待
            $log= "写入数据内容 : {$datas}\n";
            echo $log;
            file_put_contents("/data/wwwroot/php-cli/swoole.log",$log,FILE_APPEND);
        }

    }
});

守护进程启动程序,及检测启动工作进程是否正常

$ php test -d=true  # 守护进程启动
$ ps -ef | grep php  # 查看主进程是否启动运行 如果在运行可看到主进程号  Pid
                              # ps -ef | grep pool   通过进程别名可以看到更详细的信息
$ pstree -p Pid # 查看进程树 得到子进程的数量是否与进程池设定的数量是否相等,相等则表示正常          

平滑重启动和停止

$ kill -USR1 Pid # 重启
$ kill -TERM Pid # 停止

相关文章

  • pcntl信号机制配合swoole进程池 不影响业务平滑重启子进

    场景:由于公司的邮件Smtp服务器,是基于swoole的进程池实现的。但是swoole进程池,并没有平滑重启功能,...

  • 使用 swoole_process 实现 PHP 进程池

    swoole_process 主要是用来代替 PHP 的 pcntl 扩展。我们知道 pcntl 是用来进行多进程...

  • swoole中进程

    swoole-1.7.2增加了一个进程管理模块,用来替代PHP的pcntl扩展。优点:swoole_process...

  • PHP 文件锁与进程锁

    鉴于前面介绍了swoole,就借用swoole的服务器/客户端与多进程机制对锁进行说明.这里只针对PHP的锁机制进...

  • php进程认识

    1、基本认识php系统提供了pcntl_fork 函数来操作进程。pcntl_fork:当前进程位置产生分支(子进...

  • Swoole平滑重启

    Swoole平滑重启 (在服务器依然可以运行的情况下更新文件) 通过使用 sigusr1这个信号源来重启work进...

  • linux进程查杀

    kill -[信号] PID kill -1 123 (平滑重启123进程) killall [选项][信号] ...

  • Unix进程通信:信号

    信号原理 信号机制:事件促使内核向进程发送信号 事件类型:键盘按键请求内核产生信号:ctrl+c、ctrl+/等进...

  • PHP信号处理

    PHP5.3.0起支持pcntl_signal系列进程控制函数可以对信号进行安装、分发等操作。 信号处理函数 pc...

  • PHP 扩展知识

    pcntl扩展:(进程控制) pcntl扩展是进程控制的重要扩展,但目前Win不支持。包含进程创建、进程监控、...

网友评论

      本文标题:pcntl信号机制配合swoole进程池 不影响业务平滑重启子进

      本文链接:https://www.haomeiwen.com/subject/enazlhtx.html