本文目录导读:

我来详细讲解PHP中的任务调度方法,主要分为定时任务调度和异步任务调度两大类。
定时任务调度
Cron Job(Linux/Unix)
最常用的定时调度方式,在服务器crontab中配置:
# 每分钟执行 * * * * * /usr/bin/php /path/to/your/script.php # 每天凌晨2点执行 0 2 * * * /usr/bin/php /path/to/your/script.php # 每小时执行 0 * * * * /usr/bin/php /path/to/your/script.php
PHP脚本示例(script.php):
<?php
// 记录执行日志
file_put_contents('/tmp/cron.log', date('Y-m-d H:i:s')." 任务执行\n", FILE_APPEND);
// 执行具体业务逻辑
processTasks();
PHP内置的调度器(使用sleep循环)
适用于不需要精确时间的场景:
<?php
while (true) {
// 执行任务
doTask();
// 休眠60秒
sleep(60);
}
使用Laravel任务调度
Laravel提供了优雅的任务调度API:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
// 每分钟执行
$schedule->command('emails:send')->everyMinute();
// 每天午夜执行
$schedule->job(new ProcessPodcast)->daily();
// 自定义调度
$schedule->call(function () {
DB::table('users')->increment('views');
})->hourly();
}
使用workerman/crontab
Workerman框架的定时器组件:
<?php
use Workerman\Worker;
use Workerman\Lib\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$task = new Worker();
$task->onWorkerStart = function($task) {
// 每10秒执行一次
Timer::add(10, function() {
echo "任务执行中...\n";
});
// 每天2:30执行
Timer::add(86400, function() {
echo "每日任务\n";
}, [], true, strtotime('02:30') - time());
};
Worker::runAll();
异步任务调度
使用消息队列(推荐)
Redis队列实现:
<?php
// 生产者:添加任务
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$task = [
'type' => 'send_email',
'data' => ['to' => '[email protected]', 'subject' => 'Hello']
];
$redis->rPush('task_queue', json_encode($task));
// 消费者(在另一个进程中运行)
while (true) {
$task = $redis->blPop('task_queue', 0);
if ($task) {
$data = json_decode($task[1], true);
processTask($data);
}
}
使用RabbitMQ:
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
// 生产者
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('task_queue', false, true, false, false);
$msg = new AMQPMessage('Hello World!');
$channel->basic_publish($msg, '', 'task_queue');
// 消费者
$callback = function($msg) {
echo "收到: ", $msg->body, "\n";
$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
};
$channel->basic_consume('task_queue', '', false, false, false, false, $callback);
使用pcntl_fork(进程分叉)
<?php
$pid = pcntl_fork();
if ($pid == -1) {
die('无法创建子进程');
} elseif ($pid) {
// 父进程
echo "父进程继续执行\n";
pcntl_wait($status); // 等待子进程结束
} else {
// 子进程执行耗时任务
sleep(10);
echo "子进程任务完成\n";
exit(0);
}
使用GuzzleHttp异步HTTP请求
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client();
// 创建多个异步请求
$promises = [
'user' => $client->getAsync('/api/user'),
'posts' => $client->getAsync('/api/posts'),
'comments' => $client->getAsync('/api/comments')
];
// 等待所有请求完成
$results = Promise\unwrap($promises);
// 处理结果
foreach ($results as $key => $response) {
echo "$key: " . $response->getBody() . "\n";
}
完整示例:多任务调度系统
<?php
class TaskScheduler {
private $tasks = [];
private $running = true;
// 添加定时任务
public function addTask($name, $callback, $interval, $immediate = false) {
$this->tasks[] = [
'name' => $name,
'callback' => $callback,
'interval' => $interval,
'last_run' => $immediate ? 0 : time()
];
}
// 启动调度器
public function run() {
echo "调度器启动...\n";
while ($this->running) {
$current_time = time();
foreach ($this->tasks as &$task) {
if ($current_time - $task['last_run'] >= $task['interval']) {
echo date('H:i:s') . " 执行任务: {$task['name']}\n";
try {
call_user_func($task['callback']);
} catch (Exception $e) {
echo "任务失败: " . $e->getMessage() . "\n";
}
$task['last_run'] = $current_time;
}
}
sleep(1); // 每秒检查一次
}
}
public function stop() {
$this->running = false;
}
}
// 使用示例
$scheduler = new TaskScheduler();
// 添加任务:每5秒执行一次
$scheduler->addTask('task1', function() {
echo "执行task1\n";
}, 5);
// 添加任务:每10秒执行一次
$scheduler->addTask('task2', function() {
echo "执行task2\n";
}, 10);
// 启动调度器(在后台运行)
$pid = pcntl_fork();
if ($pid == 0) {
$scheduler->run();
exit(0);
}
选择建议
| 调度方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Cron Job | 固定时间间隔的任务 | 系统级支持,稳定可靠 | 最小间隔1分钟,不灵活 |
| Laravel调度 | Laravel项目 | 语法优雅,功能丰富 | 依赖Laravel框架 |
| 消息队列 | 异步任务、高并发 | 解耦、可靠、扩展性好 | 需要额外组件支持 |
| pcntl_fork | 简单并行任务 | 原生PHP,无需额外组件 | 进程管理复杂 |
| Workerman | 长连接、实时任务 | 高性能,支持高并发 | 需要常驻内存 |
最佳实践:
- 系统级定时任务使用Cron Job
- Laravel项目使用内置调度器
- 复杂的队列任务使用RabbitMQ/Redis
- 实时任务使用Workerman/Swoole
选择哪种方式取决于你的具体需求、项目架构和服务器环境。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播