如何在PHP的Redis队列中实现后台任务进度追踪?
PHP+Redis队列后台任务进度追踪方案
分场景进度追踪逻辑
针对不同类型的后台任务,进度追踪的实现需要适配任务特性:
- 数据导入(从外部API/文件导入产品至数据库):这类任务的总工作量可提前量化,比如统计待导入文件的总行数、API返回的总数据条数。假设共300条数据,每次批量导入100条,每完成一批次就更新进度:33% → 66% → 100%,进度计算精准可控。
- 大图片压缩:这类任务难以提前预估明确的阶段节点,可采用「时间估算+实时计数器」的方式:Worker启动后,参考同类型图片的历史平均压缩耗时设置进度递增节奏(比如每秒递增对应比例),每间隔固定时间将进度值写入Redis中对应
task_id的progress字段,任务完成时强制更新为100%。 - 视频格式转换:借助FFmpeg等工具获取视频总时长,在转换过程中实时读取已处理的时长比例,以此计算进度(比如已处理10秒,总时长30秒,进度就是33%),能实现精准的进度同步。
通用进度追踪代码实现
以下是适配Redis存储的PHP通用进度计算逻辑,可根据不同场景调整$total的取值逻辑:
function trackProgress(int $total, string $taskId) { echo "开始执行任务: {$taskId}" . PHP_EOL; // 初始化Redis连接(假设已完成客户端配置) $redis = new Redis(); $redis->connect('127.0.0.1', 6379); for ($i = 1; $i <= $total; $i++) { $progress = round(100 * $i / $total, 2); echo "当前进度: {$i}/{$total} ({$progress}%)" . PHP_EOL; // 将进度写入Redis,与taskId关联 $redis->hSet("task:{$taskId}", "progress", $progress); // 执行具体耗时任务(示例用sleep模拟) sleep(1); } // 任务完成,强制设置进度为100%并标记状态 $redis->hSet("task:{$taskId}", "progress", 100); $redis->hSet("task:{$taskId}", "status", "completed"); echo "任务 {$taskId} 执行完成,进度: 100%" . PHP_EOL; } // 示例调用:假设总共有10个任务单元 trackProgress(10, "task_123456");
关键注意事项
- Redis存储结构:建议用哈希表(Hash)存储任务信息,每个
task_id对应一个Hash,包含progress(进度值)、status(任务状态:pending/running/completed/failed)、start_time等字段,便于后续查询和管理。 - 异常处理:任务执行失败时,需更新进度为失败状态并记录错误信息,避免前端显示错误进度。
- 性能优化:高频写入Redis会消耗性能,可设置进度更新间隔(比如每完成10个单元更新一次,或每2秒更新一次),平衡实时性和性能。
内容的提问来源于stack exchange,提问作者jetfire21
相关产品推荐
相关产品推荐

