Laravel怎么实现队列任务执行进度百分比计算_Laravel基于总量动态估算【教程】

浅宇大大_5465

浅宇大大_5465

2026-03-28

437人浏览

原创

dispatch()后拿不到实时进度,因Laravel队列不自动记录中间状态,需任务内用Redis原子操作(如INCRBY)主动上报已完成数,并由前端按总量换算百分比。

laravel怎么实现队列任务执行进度百分比计算_laravel基于总量动态估算【教程】

为什么 dispatch() 后拿不到实时进度

因为 Laravel 队列本身不记录任务执行中的中间状态,dispatch() 只是把任务推入队列,后续由 worker 拉取并执行——整个过程默认无“进度”概念。所谓“百分比”,必须靠你自己在任务内部主动上报,再配合外部存储(如 Redis、DB)做状态快照。

常见错误现象:Job::dispatch()->onQueue('default') 后立刻查数据库或缓存,发现没数据;或者用 job->progress 这种不存在的属性直接报错。

  • 进度不是 Laravel 内置字段,$this->progress 会报 Undefined property
  • 不要依赖队列驱动(如 database、redis)自动记录执行阶段——它们只管投递和完成,不管“做到哪了”
  • 如果任务分多步但每步耗时不均(比如前 90% 是 IO 等待,后 10% 是 CPU 密集),按步骤数硬算百分比会严重失真

用 Redis + incrby 实现轻量级进度更新

Redis 的原子操作适合高频写入且无需事务保障的场景,比 DB 写入快一个数量级,也避免并发覆盖问题。关键不是存“百分比”,而是存“已完成单位数”,再由前端/接口按总量换算。

假设你有个导出 Excel 的任务,总行数已知为 $totalRows:

public function handle()
{
    $jobId = $this->job->getJobId(); // 或用 uniqid() + 任务参数哈希
    $progressKey = "job:progress:{$jobId}";
<pre class="brush:php;toolbar:false;">Redis::set($progressKey . ':total', $this->totalRows);

foreach ($this->rows as $index => $row) {
    // 处理单行...
    $done = $index + 1;
    Redis::incrby($progressKey . ':done', 1); // 原子自增

    // 每 10 行同步一次,避免 Redis 请求爆炸
    if ($done % 10 === 0 || $done === $this->totalRows) {
        $percent = round(($done / $this->totalRows) * 100);
        Redis::setex($progressKey . ':percent', 3600, $percent);
    }
}

}

  • 别用 SET 覆盖 :done,要用 INCRBY,否则并发时会丢进度
  • 不要在每次循环都写 :percent,Redis 频繁写入会拖慢任务,用定时采样更稳
  • jobId 必须全局唯一,不能只用 getJobId()(它在重试时会变),建议拼接任务类名+参数 hash

如何让前端安全读取进度而不轮询爆 Redis

前端直接 GET /api/job/progress?job_id=xxx 没问题,但得控制频率和缓存策略。重点不是“怎么查”,而是“查不到时怎么兜底”。

laravel-specialist
laravel-specialist

精通 Laravel 10+,遵循现代 PHP 实践的 Laravel 专家。擅长优雅语法、Eloquent ORM、队列系统及企业级特性...

下载

后端接口示例(Laravel Controller):

public function progress(Request $request)
{
    $jobId = $request->input('job_id');
    $key = "job:progress:{$jobId}";
<pre class="brush:php;toolbar:false;">$done = (int) Redis::get($key . ':done') ?: 0;
$total = (int) Redis::get($key . ':total') ?: 0;

// 如果 total 为 0,说明任务还没初始化好,返回 0 或 null 更合理
if ($total === 0) {
    return response()->json(['percent' => 0, 'status' => 'pending']);
}

$percent = $done >= $total ? 100 : round(($done / $total) * 100);
return response()->json([
    'percent' => $percent,
    'done' => $done,
    'total' => $total,
    'status' => $done >= $total ? 'completed' : 'running'
]);

}

  • 前端轮询间隔至少 1.5 秒起,短于 1 秒容易触发 Redis QPS 限流(尤其共享环境)
  • 如果 :total 查不到,别猜、别默认设 100,直接返回 pending,否则前端会显示“100% 但实际卡住”
  • 别在响应里塞 Redis key 名,更不要暴露 job:progress:xxx 这种结构,防止被恶意探测

重试、失败、超时场景下进度怎么不“回滚”也不“卡死”

队列任务重试时,handle() 会重新执行,但你不能让进度从 0 开始——否则用户看到“30% → 0% → 10%”就懵了。核心原则:进度只增不减,且失败后要标记状态,而非清空。

  • 在 failed() 方法里,只设 status: failed,不要删 :done 或 :percent,让用户知道“卡在哪儿了”
  • 重试时先检查 :done 是否已存在,若存在则跳过已处理部分(需你在逻辑里支持断点续传,比如加 where id > $lastDoneId)
  • 给进度 key 加过期时间(SETEX),但别设太短(比如 60 秒),否则任务跑 20 分钟,中途 Redis 清掉 key 就彻底丢失进度
  • 超时(timeout 配置)后 worker 强制 kill 进程,此时 Redis 写入可能中断,所以务必用 INCRBY + 定期采样,而不是依赖最后一步写入

最麻烦的其实是“总量动态变化”——比如边查库边导出,总数一开始根本不知道。这种就得改方案:先扫一遍计数,或用流式估算(如每万条上报一次,再按比例外推),不能硬套固定百分比模型。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

2024.04.09

877

10

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

2024.04.09

855

9

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

2024.04.09

2508

10

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.10

4701

7

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

2025.08.05

6890

22

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

2025.08.05

4516

13

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.05

8489

7

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

2026.03.04

1516

29

Laravel 框架安装指南
Laravel 框架安装指南

本指南详解 Laravel 框架安装全流程,涵盖 PHP 8.1+ 环境配置、Composer 依赖管理工具安装及国内镜像源优化。重点演示使用 composer create-project 命令创建 Laravel 10/11 项目,解决常见安装错误与依赖冲突。从环境搭建到项目初始化,助您快速完成 Laravel 开发环境部署,为后续 Web 应用开发奠定基础。适合 PHP 初学者与框架迁移开发者参考。

2026.04.09

215

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
如何安装 Composer
如何安装 Composer

共1课时 | 221人学习

Composer手册
Composer手册

共0课时 | 0人学习