frankenphp容器内存限制不能只设memory_limit,因其多线程模型下该值仅限单请求,总内存须由docker/cgroup硬限制,需按线程数×单请求常驻内存(含opcache等)估算并配置mem_limit与mem_reservation。

不能。 memory_limit 只控制单个 PHP 请求的内存上限,对 FrankenPHP 整个服务(即容器内所有线程共享的总内存)完全无效。
为什么 memory_limit 对 FrankenPHP 全局内存没用
FrankenPHP 是多线程模型,不是传统 PHP-FPM 的多进程。所有请求在线程池中复用同一进程地址空间,memory_limit 仅在 Zend 引擎层面拦截单次脚本执行的内存分配;而 OPcache、已加载扩展、框架 autoload 类、静态资源缓存等全局开销,都不受该配置约束。
一旦容器总内存超限,Linux OOM Killer 会直接杀掉整个 FrankenPHP 进程——连错误日志都不会留下,更不会触发 Fatal error: Allowed memory size exhausted。
-
memory_limit = 256M意味着每个请求最多用 256MB,但 8 个并发线程可能同时占用 8 × 30MB ≈ 240MB 常驻内存(不含峰值),再加 OPcache 的opcache.memory_consumption=128,实际已逼近 400MB - 你调大
memory_limit只会让单个坏请求拖垮更多内存,反而加速 OOM - Docker 或 cgroup 的内存限制(如
mem_limit: 512m)才是唯一能拦住总用量的防线
FrankenPHP 容器内存该设多少才安全
必须按线程数 × 单请求常驻内存(非 memory_limit)来估算,留出至少 20% 缓冲:
- 纯 API 服务(Laravel/Symfony 轻量用法 + OPcache 启用):单请求约 25–35MB → 8 线程建议
mem_limit: 384m,对应memory_limit = 256M - WordPress 或含 Mercure/Vulcain 实时推送:单请求常驻 35–45MB → 8 线程起步
mem_limit: 1g,memory_limit = 512M - 16 核高并发场景:线程数自动升到 16,容器内存至少
2g,否则 OOM 频发
别信“设了 memory_limit 就万事大吉”——FrankenPHP 容器不显式设 mem_limit,等于把进程裸奔扔进生产环境。
docker-compose.yml 中必须写的两行
只写 mem_limit 不够,还要配 mem_reservation 防止突发抖动被误杀:
services:
app:
image: dunglas/frankenphp
mem_limit: 1g
mem_reservation: 512m
同时确保:memory_limit(php.ini)≤ mem_reservation × 0.8,例如 reservation 设 512MB,memory_limit 最高设 400M。
漏掉 mem_reservation 的后果是:容器刚启动就因瞬时内存抖动被 OOM Killer 杀掉,尤其和 MySQL、Redis 共部署时特别明显。
最常被忽略的一点:FrankenPHP 的线程数默认为 num_threads auto,它会根据 CPU 核数自动调整——你改了宿主机配置或换了机器,线程数就变,内存需求也跟着变。别只测一次就定死配置。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











