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()
}

 不过如果单这个还是有可能会断,所以需要加个定时器检测这个进程是否存在,如果不存在重新开启

posted @ 2021-04-03 11:02  萧声幽篱  阅读(188)  评论(0)    收藏  举报