温馨提示×

Ubuntu如何解决Laravel内存溢出

小樊
43
2025-12-14 15:27:28
栏目: 智能运维

Ubuntu下解决Laravel内存溢出的实用方案

一 快速定位与临时缓解

  • 明确触发场景:是 Web 请求Artisan 命令、还是 队列 Worker
  • 临时放宽内存上限(仅用于排查或一次性任务):
    • 修改 PHP 配置(CLI 与 FPM 可能不同):/etc/php/7.x/cli/php.ini 或 /etc/php/7.x/fpm/php.ini,设置 memory_limit = 256M/512M;FPM 需重启服务。
    • 在命令前临时生效:
      • Web:在入口或中间件中 ini_set('memory_limit', '512M');
      • Artisan:在命令类或调用处 ini_set('memory_limit', '1G');
    • 注意:这只是权宜之计,需配合后续优化。
  • 排查命令行的“假内存不足”:
    • 关闭查询日志:DB::connection()->disableQueryLog();
    • 避免把整个结果集一次性装入内存:用 游标 cursor()分块 chunk() 处理大数据。

二 代码与查询层面的根治

  • 大数据导出/批处理:
    • 使用 LazyCollection cursor() 逐行处理,避免 get() 把全部记录装入内存。
    • 或用 chunk(10000…) 分页处理,边取边写,释放每批数据。
  • 优化查询与关联:
    • 解决 N+1 问题,使用 with(‘relation’) 预加载。
    • 只选需要的字段,避免 select *
  • 减少日志与事件带来的内存压力:
    • 长时任务或常驻进程可临时关闭查询日志:DB::connection()->disableQueryLog();
    • 排查第三方包对日志事件的监听(如 Facade/IgnitionLogRecorder 会累积日志到内存),必要时移除或在循环内手动 app()->make(LogRecorder::class)->reset(); 释放。

三 运行环境与进程管理

  • 启用并优化 OPcache(减少重复编译带来的 CPU 与内存压力):
    • zend_extension=opcache.so
    • opcache.enable=1
    • opcache.memory_consumption=128
    • opcache.interned_strings_buffer=8
    • opcache.max_accelerated_files=4000
    • opcache.revalidate_freq=60
  • 使用 队列 Worker 处理耗时任务,避免阻塞请求进程:
    • 配置 Supervisor 守护:sudo apt-get install supervisor
    • 启动:php artisan queue:work --queue=high,default --tries=3 --sleep=3
  • 监控与维护:
    • 监控内存:htoptopfree -m
    • 必要时定期重启服务(如异常增长):sudo systemctl restart php**7.x**-fpmsudo systemctl restart apache2

四 常见场景与对应措施

场景 主要成因 推荐措施
Web 请求偶发 OOM 查询未优化、加载过多关联、日志/事件累积 优化查询与关联(with、字段筛选)、减少日志级别与事件监听、必要时临时上调 memory_limit
Artisan 大数据导出 一次性 get()、开启查询日志 使用 cursor()chunk()、关闭查询日志、分批写入文件
队列 Worker 常驻内存上涨 日志/查询记录器在循环中累积 在循环内调用 LogRecorder::reset()、移除不必要的日志监听、控制日志级别与保留策略
配置已改仍 OOM CLI 与 FPM 配置不一致、OPcache 未启用 同步修改 CLI 与 FPM 的 php.ini、重启 FPM、启用并调优 OPcache

0