在 laravel 队列任务中应使用 memory_get_usage(true) 在 handle() 开头和结尾分别采样,取差值得到单任务真实内存增量,避免误用 memory_get_usage() 或 memory_get_peak_usage();oom 导致的静默退出需通过 dmesg 确认;cli 下 memory_limit 应按实测增量合理设置,如平均增 80mb 则设 256m,并配合 --max-time 防泄漏。

怎么在 Laravel 队列任务里实时看内存用了多少
直接在任务执行中用 memory_get_usage(true) 拿当前内存占用,别用 memory_get_usage()(它不包含未释放的 PHP 内部分配,容易低估)。Laravel 的队列 worker 是长生命周期进程,内存只增不减是常态,光看“当前用量”没意义,得看“本次任务新增了多少”。
- 在任务
handle()开头记一次memory_get_usage(true),结尾再记一次,差值才是这次任务真实内存增量 - 别依赖
memory_get_peak_usage()—— 它返回的是整个 worker 进程启动以来的峰值,不是单个任务的 - 如果任务里调了第三方 SDK 或大文件处理,记得在关键节点(比如解压后、JSON 解析完)插点采样,否则可能错过瞬时尖峰
Laravel 队列任务内存超限被 kill 怎么定位
Linux 下常表现为任务静默退出、日志里只有 Killed 二字,没有 PHP 错误或异常堆栈 —— 这是 OOM Killer 干的,不是 Laravel 或 PHP 报的错。
- 先确认是否真被 OOM 杀:查系统日志
dmesg -T | grep -i "killed process",会看到类似Killed process 12345 (php) total-vm:2.1g, anon-rss:1.8g - Laravel 日志里不会记录这个,
failed_jobs表也不会写入,因为进程被信号 SIGKILL 强制终止,连__destruct()都不执行 - 临时加防护:在
handle()开头加ini_set('memory_limit', '512M')(注意单位必须带 M),比不设更可控;但治标不治本,得配合内存采样找泄漏点
用 Laravel Telescope 记录内存曲线靠谱吗
Telescope 默认不采集内存数据,要自己加扩展。它适合观测单次请求或任务的内存趋势,但对长周期队列 worker 不适用 —— 因为 Telescope 的 snapshot 是按 request/job 生命周期存的,而一个 worker 进程跑几百个 job,内存只涨不跌,曲线会一路冲高然后平掉,看不出单个任务波动。
- 想用 Telescope,得在
JobProcessing和JobProcessed事件里手动打点,把memory_get_usage(true)值塞进Telescope::recordMessage() - 注意别在
JobFailed里记 —— OOM 导致的失败根本进不来这个事件 - 更轻量的做法:直接往自定义日志里写 CSV 行,比如
date("Y-m-d H:i:s") . "," . $jobId . "," . memory_get_usage(true) . "\n",后续用脚本抽数据画图
PHP CLI 模式下 memory_limit 设多少才合理
别盲目设成 -1 或 2G。CLI 的 memory_limit 是 per-process 限制,队列 worker 启多个进程时,总内存消耗是倍数关系。比如开 4 个 queue:work --max-jobs=100 进程,每个设 1G,极端情况下可能吃掉 4G 物理内存。
- 推荐策略:根据单个任务实测内存增量设限,比如测出来平均新增 80MB,就设
256M,留足够余量但不过度宽松 -
php.ini里的全局memory_limit对 CLI 无效,必须在启动命令里显式指定:php -d memory_limit=256M artisan queue:work - 用
--max-time=3600配合内存监控更稳妥:避免某个任务缓慢泄漏,占着进程不放,拖垮整组 worker
内存监控真正的难点不在采集,而在区分“合理增长”和“异常泄漏”——比如一个任务读 100MB 文件,内存涨 120MB 是正常的;但连续跑 10 次,每次涨 15MB,第 10 次涨到 280MB,这就是典型泄漏。得靠增量对比 + 多次运行基线比对,不能只看单次数字。











