php 队列实现
使用数据库实现队列
在PHP中可以通过数据库表模拟队列行为,创建包含id、data、status和created_at字段的表。插入数据时状态设为pending,消费时更新为processing,完成后标记为processed。
// 生产者示例
$data = ['task_type' => 'email', 'content' => 'Hello'];
DB::table('jobs')->insert([
'data' => json_encode($data),
'status' => 'pending',
'created_at' => now()
]);
// 消费者示例
$job = DB::table('jobs')
->where('status', 'pending')
->orderBy('created_at')
->first();
if ($job) {
DB::table('jobs')
->where('id', $job->id)
->update(['status' => 'processing']);
// 处理任务逻辑
processJob(json_decode($job->data, true));
DB::table('jobs')
->where('id', $job->id)
->update(['status' => 'processed']);
}
使用Redis列表实现队列
Redis的LPUSH和RPOP命令天然适合队列操作。将序列化后的任务数据存入列表,消费者从另一端获取任务。
// 生产者
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$task = serialize(['action' => 'generate_report', 'params' => []]);
$redis->lPush('task_queue', $task);
// 消费者
while (true) {
$task = $redis->rPop('task_queue');
if ($task) {
$data = unserialize($task);
handleTask($data);
}
sleep(1); // 避免空轮询
}
使用专业队列系统
对于生产环境,建议使用专业的队列系统如RabbitMQ或Beanstalkd。Laravel框架内置队列支持,配置文件位于config/queue.php。
安装Beanstalkd扩展后配置:
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
],
创建任务类:
php artisan make:job ProcessPodcast
分发任务:
ProcessPodcast::dispatch($podcast);
启动队列处理器:
php artisan queue:work
实现优先级队列
在Redis中可以通过多个列表实现优先级。高优先级任务放入high_queue,普通任务放入default_queue,消费者优先检查高优先级队列。
// 多优先级生产者
$redis->lPush('high_queue', serialize($urgentTask));
$redis->lPush('default_queue', serialize($normalTask));
// 多优先级消费者
$task = $redis->rPop('high_queue')
?: $redis->rPop('default_queue');
处理失败任务
专业队列系统通常提供失败重试机制。Laravel队列允许设置最大尝试次数和重试延迟:
public $tries = 3;
public $backoff = [60, 120, 300];
手动处理失败任务:

public function failed(Exception $exception)
{
// 记录失败日志
Log::error('Job failed: '.$exception->getMessage());
}






