基于Swoole的Process进程管理模块支付结果回调服务

原先用PHP的Pthread多线程实现的支付结果回调服务,在后期运行中出现了服务停止的问题,在学习swoole的过程中,发现可以用swoole的Process进程管理模块实现多线程的功能,并且使用swoole_time_tick定时器功能实现进程监控在子进程退出的时候进行重启。

1、开发环境

    Swoole版本:2.0.12

    PHP版本:7.1

    服务器版本:Ubuntu 14.04 64位

2、业务场景

    游戏APP在支付后,在支付宝,微信等回调支付结果后,将支付结果回调给游戏服务器。回调逻辑为:25 小时以内完成 8 次通知(通知的间隔频率一般是:0s,2m,10m,10m,1h,2h,6h,15h)。第一次通知在接收到结果时同时回调。所以另外7次间隔性回调由7个进程分别操作。每个进程服务运行时间不一致,当前业务时间间隔各为1s,2s,30s,30s,60s,300s,600s,600s一次

3、代码实例

use Swoole\Process;

class MyProcess
{
    public $mpid = 0; // master pid, 即当前程序的进程ID
    public $works = []; // 记录子进程的 pid
    public $maxProcessNum = 7;
    public $newIndex = 1;

    public function __construct()
    {
        try {
            swoole_set_process_name(' MyProcess : master');
            $this->mpid = posix_getpid();
            $this->run();
            $this->processWait();
        } catch (\Exception $e) {
            die('Error: '. $e->getMessage());
        }
    }

    public function run()
    {
        //创建进程
        for ($i=0; $i<=$this->maxProcessNum; $i++) {
            $this->createProcess($i);
        }
    }


    public function createProcess($index = null)
    {
        if (is_null($index)) {
            $index = $this->newIndex;
            $this->newIndex++;
        }
        echo date('Y-m-d H:i:s') . '  |  createProcess index='.$index.PHP_EOL;
        $process = new swoole_process(function (swoole_process $worker) use($index) { // 子进程创建后需要执行的函数
            swoole_set_process_name(" MyProcess : worker $index");
            //根据进程启用不同时间间隔的定时器 $ms为毫秒 支付回调7次尝试 7个进程回调服务 每次回调的间隔时间不一致,实行25 小时以内完成 8 次通知(通知的间隔频率一般是:2m,10m,10m,1h,2h,6h,15h)
            switch ($index) {
                case 0;
                    $ms = 1000;
                    break;
                case 1;
                    $ms = 2000;
                    break;
                case 2;
                    $ms = 30000;
                    break;
                case 3;
                    $ms = 30000;
                    break;
                case 4;
                    $ms = 60000;
                    break;
                case 5;
                    $ms = 300000;
                    break;
                case 6;
                    $ms = 600000;
                    break;
                case 7;
                    $ms = 600000;
                    break;
            }
            //启用定时器
            $timer=swoole_timer_tick($ms,'MyProcess::deal_pay_notify', $index);

        }, false, false); // 不重定向输入输出; 不使用管道
        $pid = $process->start();
        $this->works[$index] = $pid;
        return $pid;
    }

    /*
        * 处理支付回调
        */
    function deal_pay_notify($timmerID, $params){
        echo date('Y-m-d H:i:s') . '  |  timmerID='.$timmerID." params=".$params.PHP_EOL;

        //支付结果回调操作
        //......

    }

    // 重启子进程
    public function rebootProcess($pid)
    {
        $index = array_search($pid, $this->works);
        if ($index !== false) {
            //重新创建进程
            $newPid = $this->createProcess($index);
            echo "rebootProcess: {$index}={$pid}->{$newPid} Done\n";
            return;
        }
        throw new \Exception("rebootProcess error: no pid {$pid}");
    }


    // 监控子进程
    public function processWait()
    {
        //定时器每秒监控
        swoole_timer_tick(1000,'MyProcess::monitor_process', '');
        /*while (1) {
            if (count($this->works)) {
                $ret = Process::wait(); // 子进程退出
                if ($ret) {
                    $this->rebootProcess($ret['pid']);
                }
            } else {
                break;
            }
        }*/
    }

    //检测进程
    public function monitor_process($timmerID, $params){
        foreach($this->works as $pid){
            if (!Process::kill($pid, 0)) { // 0 可以用来检测进程是否存在
                $this->rebootProcess($pid); //重启进程
                echo date('Y-m-d H:i:s') . '  |  monitor_process pid='.$pid. ' restart'.PHP_EOL;
            }
        }
    }
}

new MyProcess();

 

gitee:https://gitee.com/oydm/codes/ktc358gd1w02ufnel6zr413

 

转载于:https://my.oschina.net/wemesky/blog/1630517

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值