webman内存优化核心是控单进程rss、压总进程数、绕内存雷区:先实测rss,按公式(总内存mb×0.8÷单进程rss)算最大安全count;禁用$cache=[]等进程内缓存;大文件上传必须用php://input流式处理。

Webman 的内存问题不是“调个参数就解决”,而是多进程模型下每个 Worker 独占内存、不共享、不回收的硬约束。优化核心是:控住单进程 RSS、压住总进程数、绕过内存雷区。
Worker 进程数 $worker->count 怎么设才不 OOM
设高了直接爆内存,设低了 CPU 闲着、请求排队——这不是理论问题,是每台机器上都能复现的 ps aux --sort=-%mem | grep php 真实数据问题。
- 先实测单 Worker RSS:上线后稳定运行 5 分钟,用
ps aux --sort=-%mem | grep php抓 3–5 个 Worker 的%MEM值,换算成 MB(比如 1.2% × 16GB = 192MB),取平均值 - 最大安全
count=(总内存MB × 0.8) ÷ 单进程RSS(MB),例如 16GB 机器实测 RSS 48MB →16384 × 0.8 ÷ 48 ≈ 273,那就别设超过 270 - IO 密集型(用
mysqli、pdo_mysql、redis->get())起步用 CPU 核数 × 3;CPU 密集型(协程 MySQL、纯计算)就设 CPU 核数或 +1 -
$worker->reusePort = true不是救命稻草——它只缓解内核惊群,不省内存,也不提升单进程吞吐;若已逼近 RSS 上限,开它反而因哈希表膨胀略增延迟
为什么 $cache = [] 是 Webman 里最隐蔽的内存泄漏源
多 Worker 进程下,每个进程都有自己的 PHP 内存空间。static::$cache 或全局数组写进去的数据,别的进程根本看不到,还越积越大收不回来。
- 错误现象:
Cache::get('user:1001')在 A 请求写入,B 请求读不到;限流计数在进程 A 到 99,进程 B 还从 0 开始 - 唯一能用本地数组的场景:仅限
Worker::$processCount = 1的单进程调试,或一次请求内临时复用(如函数多次调用结果缓存) - 真要缓存,必须走
webman/redis连接池,且 Key 必须含业务域 + 参数签名(用json_encode()哈希)+ 显式版本号(如v2),否则换分页逻辑或切环境就串数据
大文件上传时 move_uploaded_file 为什么必然触发 OOM
PHP 默认上传流程强制走 $_FILES,整个文件先完整写进 upload_tmp_dir,再由 move_uploaded_file 搬运——这对 Webman 常驻进程是架构级硬伤。
-
upload_max_filesize和post_max_size会在请求层直接拦截超限请求(返回 413 或空白页) - 即使绕过限制,
$_FILES['file']['tmp_name']加载后,move_uploaded_file内部仍会尝试映射或复制整个文件句柄;2GB 文件会让 Worker RSS 瞬间飙高 - 正确路径只有
php://input:前端改用fetch发application/octet-stream,后端跳过$_FILES,用stream_copy_to_stream()流式落盘分片,合并时也必须流式拼接(fopen($final, 'wb')+while (fread)),绝不能file_get_contents
Webman 的内存管理没有“银弹”。关键不是堆多少配置,而是盯住 ps aux 里的真实 RSS、禁掉所有依赖 $_FILES 的封装、把缓存彻底移出进程内存——这些动作不做,其他调优都是给爆炸倒计时加速。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











