PHP执行定时任务的解决方案
定时运行任务对于一个网站来说,是一个比较重要的任务,比如定时发布文档,定时清理垃圾信息等,现在的网站大多数都是采用PHP动态语言开发的,而对于PHP-FPM的实现决定了它没有Java和.Net这种AppServer的概念,而http协议是一个无状态的协议,PHP-FPM只能被用户触发,被调用,调用后会自动退出内存,没有常驻内存。
其实不然,PHP定时任务有以下几种解决方案
简单直接的方案
<?php
ini_set('memory_limit','512M'); // 设置内存限制
$interval=60*30;// 每隔半小时运行
do{
//ToDo
sleep($interval);
}
while(true);
执行
nohup php myphp.php > log.txt &
缺点:占系统资源, 长时间运行,会有一些意想不到的隐患。比如内存管理方面的问题和稳定性方面的问题
使用pcntl扩展
<?php
$pid = pcntl_fork();
//父进程和子进程都会执行下面代码
if ($pid == -1) {
//错误处理:创建子进程失败时返回-1.
die('could not fork');
} else if ($pid) {
//父进程会得到子进程号,所以这里是父进程执行的逻辑
pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
} else {
$interval=60*30;// 每隔半小时运行
//子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
do{
//ToDo
require 'test.php';
sleep($interval);
}
while(true);
}
执行
nohup php myphp.php > log.txt &
在unix系统下执行,在Crontab中使用PHP执行脚本
00 * * * * /usr/local/bin/php /home/root/test.php
使用workerman框架
<?php
use \Workerman\Worker;
use \Workerman\Lib\Timer;
require_once __DIR__ . '/Workerman/Autoloader.php';
$task = new Worker();
// 开启多少个进程运行定时任务,注意业务是否在多进程有并发问题
$task->count = 1;
$task->onWorkerStart = function($task)
{
// 每2.5秒执行一次
$time_interval = 2.5;
Timer::add($time_interval, function()
{
echo "task run\n";
});
};
// 运行worker
Worker::runAll();
使用swoole扩展
<?php
//1s执行一次
swoole_timer_tick(1000, function($timerid,$para){
echo "timeout\n";
},$param);
以上是常用的PHP定时任务实现方案。各有优缺点,推荐后三种方案,方便可控