本文目录导读:

我来详细介绍PHP定时任务的部署方法,从简单到复杂,适合不同场景的使用。
Linux Crontab(最常用)
基本用法
# 编辑定时任务 crontab -e # 查看定时任务 crontab -l # 格式:分 时 日 月 周 命令 * * * * * command
PHP脚本示例
# 每分钟执行一次 * * * * * /usr/bin/php /var/www/html/cron.php # 每天凌晨2点执行 0 2 * * * /usr/bin/php /var/www/html/cron.php # 每周一凌晨3点执行 0 3 * * 1 /usr/bin/php /var/www/html/cron.php # 每月1号凌晨4点执行 0 4 1 * * /usr/bin/php /var/www/html/cron.php
安全执行方式
# 使用日志记录 0 2 * * * /usr/bin/php /var/www/html/cron.php >> /var/log/cron.log 2>&1 # 限制执行时间 0 2 * * * timeout 300 /usr/bin/php /var/www/html/cron.php
Windows任务计划程序
创建批处理文件
@echo off C:\PHP\php.exe C:\www\cron.php
设置任务计划
# 创建定时任务(管理员权限) schtasks /create /tn "PHP任务" /tr "C:\cron.bat" /sc daily /st 02:00
使用PHP实现守护进程
无限循环执行
<?php
// daemon.php
set_time_limit(0);
ini_set('memory_limit', '512M');
while (true) {
// 执行任务
echo date('Y-m-d H:i:s') . " - Task executed\n";
// 写入日志
file_put_contents('/var/log/php_cron.log',
date('Y-m-d H:i:s') . " - Task executed\n", FILE_APPEND);
// 休眠60秒
sleep(60);
// 检查内存使用
if (memory_get_usage() > 100 * 1024 * 1024) {
gc_collect_cycles(); // 触发垃圾回收
}
}
?>
启动守护进程
# 后台运行 nohup php daemon.php > /dev/null 2>&1 & # 查看进程 ps aux | grep daemon.php # 停止进程 kill $(pgrep -f daemon.php)
使用Supervisor(推荐)
安装配置
# 安装 apt install supervisor # 配置守护进程 vim /etc/supervisor/conf.d/php-worker.conf [program:php-worker] command=php /var/www/app/worker.php directory=/var/www/app autostart=true autorestart=true startsecs=3 startretries=5 redirect_stderr=true stdout_logfile=/var/log/php-worker.out.log stderr_logfile=/var/log/php-worker.err.log
管理命令
# 重新加载配置 supervisorctl reread supervisorctl update # 启动/停止/重启 supervisorctl start php-worker supervisorctl stop php-worker supervisorctl restart php-worker # 查看状态 supervisorctl status
使用Redis队列(适合分布式)
生产者代码
<?php
// add_to_queue.php
require 'vendor/autoload.php';
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 添加任务到队列
$task = [
'type' => 'send_email',
'to' => 'user@example.com',
'data' => ['message' => 'Hello World']
];
$redis->lpush('task_queue', json_encode($task));
消费者代码
<?php
// worker.php
require 'vendor/autoload.php';
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
while (true) {
// 阻塞读取队列
$task = $redis->brpop('task_queue', 30);
if ($task) {
processTask(json_decode($task[1], true));
}
usleep(1000000); // 1秒延迟
}
function processTask($data) {
switch ($data['type']) {
case 'send_email':
sendEmail($data['to'], $data['data']);
break;
// 其他任务类型
}
}
使用消息队列组件
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);
echo "等待任务... Ctrl+C 退出\n";
$callback = function ($msg) {
echo "收到任务: ", $msg->body, "\n";
// 处理任务
processTask($msg->body);
$msg->ack();
};
$channel->basic_qos(null, 1, null);
$channel->basic_consume('task_queue', '', false, false, false, false, $callback);
while (count($channel->callbacks)) {
$channel->wait();
}
最佳实践配置
基础Crontab配置模板
# 编辑定时任务 crontab -e # ===== 常用PHP定时任务 ===== # 每小时执行数据备份 0 * * * * /usr/bin/php /var/www/html/backup.php >> /var/log/backup.log 2>&1 # 每天清理临时文件 0 2 * * * /usr/bin/php /var/www/html/cleanup.php >> /var/log/cleanup.log 2>&1 # 每周生成统计报表 0 3 * * 1 /usr/bin/php /var/www/html/report.php >> /var/log/report.log 2>&1 # 每月清理旧数据 0 4 1 * * /usr/bin/php /var/www/html/archive.php >> /var/log/archive.log 2>&1 # 节假日提醒(每天检查) * * * * * /usr/bin/php /var/www/html/check_holiday.php >> /var/log/holiday.log 2>&1
PHP脚本最佳实践
<?php
// cron.php
class CronTask
{
private $logFile;
public function __construct($logFile = '/var/log/php_cron.log')
{
$this->logFile = $logFile;
}
public function execute()
{
try {
$this->log('任务开始执行');
// 1. 检查是否已在运行
if (!$this->checkRunning()) {
$this->log('任务已在运行,跳过执行');
return false;
}
// 2. 设置锁
$this->setLock();
// 3. 执行任务
$this->doTask();
// 4. 清理锁
$this->removeLock();
$this->log('任务执行完成');
return true;
} catch (Exception $e) {
$this->log('任务执行失败: ' . $e->getMessage());
$this->removeLock();
return false;
}
}
private function checkRunning()
{
// 检查PID文件
return !file_exists('/tmp/cron.lock');
}
private function setLock()
{
file_put_contents('/tmp/cron.lock', getmypid());
}
private function removeLock()
{
@unlink('/tmp/cron.lock');
}
private function doTask()
{
// 实际业务代码
// ...
}
private function log($message)
{
$log = date('Y-m-d H:i:s') . " - " . $message . "\n";
file_put_contents($this->logFile, $log, FILE_APPEND);
}
}
$cron = new CronTask();
$cron->execute();
选择建议
| 场景 | 推荐方案 | 优点 | 缺点 |
|---|---|---|---|
| 简单定时任务 | Crontab | 简单、效率高 | 不支持并行 |
| Windows环境 | 任务计划程序 | 系统自带 | 可扩展性差 |
| 复杂任务管理 | Supervisor | 可监控、自动重启 | 需要安装 |
| 分布式任务 | Redis/RabbitMQ | 可扩展、解耦 | 需要维护额外服务 |
| 长期运行任务 | 守护进程 | 实时执行 | 资源占用高 |
注意事项
- 防止重复执行:使用锁机制或检查PID
- 错误处理:记录日志、发送邮件告警
- 资源控制:设置内存和执行时间限制
- 性能监控:记录执行时间和内存占用
- 容错机制:失败自动重试或继续下次计划
选择哪种方案取决于你的具体需求,建议从简单的Crontab开始,随着业务增长再考虑更复杂的方案。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播