php创建守护进程
介绍
应领导的要求做了一个短信平台,就是简单的记录某些应用通过api发的短信数量,一开始因为发的数量少,所以采取直接发的形式,但是随着应用的多,慢慢发现直接CURL发送太耗费时间,一次性发几百条可能都要好几分钟,所以打算用php进程形式发送。
1、开始
业务就不介绍了,具体讲技术实现的过程。
因为当前请求也不是很多,所以队列采用的mysql数据表的形式(方便记录),提交插入数据表,返回成功。后台进程实时去获取数据表,是否有最新插入的数据,没有->返回,有->执行发送短信请求。
前台的代码好实现,但是写后台进程的代码就有一些磕磕碰碰了,在此记录一下。
启动进程的文件为send.php
一开始以为php send.php &就行了,发现过个几小时就断了。
觉得是mysql断线重连的关系,使用了第三方类
http://github.com/joshcam/PHP-MySQLi-Database-Class
再启动,又过个几个小时又断了,就是用try,catch也没发现有任何的报错,查了百度,原来linux进程运行过长会停掉,那怎么办,要用守护进程(查的)。
2,守护进程
php写守护进程需要用到posix、pctl扩展(应该这么叫吧,反正要用到几个相关函数)
下面是代码,也是网上抄的,就是记录下:
$pid = pcntl_fork(); if ($pid < 0) { throw new Exception('fork子进程失败'); } elseif ($pid > 0) { //父进程退出,子进程不是进程组长,以便接下来顺利创建新会话 exit(0); } // 最重要的一步,创建一个新的会话,脱离原来的控制终端 posix_setsid(); // 修改当前进程的工作目录,由于子进程会继承父进程的工作目录,修改工作目录以释放对父进程工作目录的占用。 chdir('/'); /* * 通过上一步,我们创建了一个新的会话组长,进程组长,且脱离了终端,但是会话组长可以申请重新打开一个终端,为了避免这种情况,我们再次创建一个子进程,并退出当前进程,这样运行的进程就不再是会话组长。 */ $pid = pcntl_fork(); if ($pid < 0) { throw new Exception('fork子进程失败'); } elseif ($pid > 0) { // 再一次退出父进程,子进程成为最终的守护进程 exit(0); } // 由于守护进程用不到标准输入输出,关闭标准输入,输出,错误输出描述符 fclose(STDIN); fclose(STDOUT); fclose(STDERR); /** 业务代码 */ //记录运行进程 $cid = posix_getpid(); file_put_contents('./data/sendfork.txt',$cid); require_once ('./MySQLiDb/MysqliDb.php'); $host=""; //数据库的用户名 $user=""; //数据库的密码 $password=""; //不知道$db资源放在哪,姑且先放在着,到时再看 $db = new MysqliDb ($host, $user, $password, '表'); //查看进程 ps -ef|grep php 杀死进程 kill -9 pid while(TRUE) { //业务代码 //记得释放变量 unset() }
不过如果单这个还是有可能会断,所以需要加个定时器检测这个进程是否存在,如果不存在重新开启
萧声幽篱

浙公网安备 33010602011771号