原来用PHP的Pthread多线程服务实现的支付结果回调服务在后面的运行中停止了。在学习swoole的过程中,发现swoole可以使用Process进程管理模块实现多线程功能,使用swoole_time_tick定时器功能实现进程监控,子进程退出时重启。1、开发环境Swoole版本:2.0.12PHP版本:7.1服务器版本:Ubuntu14.0464位2、业务场景支付后,游戏APP通过支付宝、微信等回调,将支付结果回调给游戏服务器支付结果。回调逻辑为:25小时内完成8次通知(通知间隔频率一般为:0s、2m、10m、10m、1h、2h、6h、15h)。第一个通知在收到结果的同时回调。所以另外7个区间回调分别由7个进程操作。各进程服务运行时间不一致,当前业务时间间隔为1s、2s、30s、30s、60s、300s、600s、600s一次3.代码示例useSwoole\Process;classMyProcess{public$mpid=0;//masterpid,即当前程序的进程号public$works=[];//记录子进程的pidpublic$maxProcessNum=7;公共$newIndex=1;publicfunction__construct(){try{swoole_set_process_name('MyProcess:master');$this->mpid=posix_getpid();$this->run();$this->processWait();}catch(\Exception$e){die('Error:'.$e->getMessage());}}publicfunctionrun(){//创建进程($i=0;$i<=$this->maxProcessNum;$i++){$this->createProcess($i);}}publicfunctioncreateProcess($index=null){if(is_null($index)){$index=$this->newIndex;$this->newIndex++;}回声日期('Y-m-dH:i:s')。'|createProcessindex='.$index.PHP_EOL;$process=newswoole_process(function(swoole_process$worker)use($index){//子进程创建后需要执行的函数swoole_set_process_name("MyProcess:worker$index");//开启不同时间的定时器intervalsaccordingtotheprocess$ms为毫秒支付回调7次尝试7个流程回调服务每次回调的间隔时间不一致,25小时内完成8次通知(通知的间隔频率一般为:2m、10m、10m、1h,2h,6h,15h)switch($index){case0;$ms=1000;break;case1;$ms=2000;break;case2;$ms=30000;break;case3;$ms=30000;中断;案例4;$ms=60000;中断;案例5;$ms=300000;中断;案例6;$ms=600000;中断;案例7;$ms=600000;中断;}//启用定时器$timer=swoole_timer_tick($ms,'MyProcess::deal_pay_notify',$index);},假的,假的);//不重定向输入输出;不要使用管道$pid=$process->start();$this->works[$index]=$pid;返回$pid;}/**处理支付回调*/functiondeal_pay_notify($timmerID,$params){echodate('Y-m-dH:i:s').'|timmerID='.$timmerID."params=".$params.PHP_EOL;//支付结果回调操作//...}//重启子进程publicfunctionrebootProcess($pid){$index=array_search($pid,$this->works);if($index!==false){//重新创建进程$newPid=$this->createProcess($index);echo"rebootProcess:{$index}={$pid}->{$newPid}完成\n";返回;}thrownew\Exception("rebootProcesserror:nopid{$pid}");}//监听子进程publicfunctionprocessWait(){//定时器监听swoole_timer_tick(1000,'MyProcess::mon每秒itor_process','');/*while(1){if(count($this->works)){$ret=Process::wait();//子进程退出if($ret){$this->rebootProcess($ret['pid']);}}else{休息;}}*/}//检测进程publicfunctionmonitor_process($timmerID,$params){foreach($this->worksas$pid){if(!Process::kill($pid,0)){//0可以用来检测进程是否存在$this->rebootProcess($pid);//重启进程echodate('Y-m-dH:i:s').'|monitor_processpid='.$pid.'重启'.PHP_EOL;}}}}newMyProcess();gitee:https://gitee.com/oydm/codes/...
