php-fpm守护,PHP使用守护进程处理队列

一.概述

项目是棋牌,web架构是典型的lnmp,server产生的牌局通过http协议请求webserver,由php分析并持久化到mysql,中间参杂了很多业务逻辑,整个流程耗时平均接近2s。

这种方式存在以下2个问题

1.整个流程是同步的,server会一直等待php响应,一旦server处理不慎,会造成server阻塞,玩家无法玩牌。

2.如果牌局数量较多,会占用较多的php-fpm进程,可能造成php-fpm无法处理其他业务。

二.改进方式

后面改由server把牌局数据写到redis队列里,php使用守护进程处理redis队列。

cron每5分钟运行gamelog.php,gamelog检测牌局队列数量,根据队列的数量动态fork对应的子进程处理牌局业务,当子进程数量有多余的空闲进程,gamelog.php

会杀掉多余的进程,这种方式参考了php-fpm的dynamic模式,具体实现如下:

define('LEN', 50);//单进程处理牌局队列长度

define('PROC_MIN', 2);//最小进程数

define('PROC_MAX', 5);//最大进程数

ini_set('memory_limit', '128M');umask(002);set_time_limit(0);//cli模式非必须

$daemonNum = (int) `ps -ef | grep "gamelog.php" | grep -v grep | awk '$3 == 1 {print $2}' | wc -l`;//当前守护进程数

$appGameLog = app::gamelog();$appRedis = app::redis('log');$key = akey::gamelog();$len = $appRedis->lSize($key);$wokerNum = ceil($len / LEN);//需要的进程数

($wokerNum < PROC_MIN) && ($wokerNum =PROC_MIN);if($daemonNum < $wokerNum){//守护进程数小于需要开启的进程数

$procNum = $wokerNum - $daemonNum;$procNum = min($procNum,PROC_MAX);$procNum = max($procNum,PROC_MIN);for($p = 1; $p <= $procNum; $p++){$pid =pcntl_fork();if($pid == 0){

posix_setsid();while(true){$data = $appRedis->rPop($key);//此处处理业务

}exit;

}else if($pid > 0){

}else{exit("fork error");

}

}

}else if($daemonNum > $wokerNum){//进程数过多自行kill

$pidStr = `ps -ef | grep "gamelog.php" | grep -v grep | awk '$3 == 1 {print $2}'`;$aPid = explode(PHP_EOL, $pidStr);$wokerNum = max($wokerNum, PROC_MIN);//最少保留PROC_MIN个守护进程

$killNum = $daemonNum - $wokerNum;foreach($aPid as $pid){$pid = (int) $pid;if($pid <= 0){continue;

}if(posix_kill($pid,SIGKILL)){if(--$killNum <= 0){break;

}

}

}

}

php执行shell命令除了system(),exec(),还可以使用``。

posix_setsid()函数php手册里只有一句说明 Make the current process a session leader

posix_setsid对应的unix系统函数是setsid(),当进程调用setsid会产生一个新的会话,而且这个进程将不受终端控制

之前进程有终端控制也会被解除,所以我们在命令行启动gamelog.php,然后关掉终端不会杀掉gamelog.php产生的子进程

三.改进后的效果

1.改进后server写redis队列远比通过http协议请求php快,极大减少了server等待牌局处理的时间。

2.php-fpm不用处理牌局的请求,改由后台进程处理,释放了php-fpm。

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3mj93mrrhoqos

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值