Nginx与PHP体量限制不匹配怎么排查?

1 人参与

很多站长或运维在调整服务器配置时,经常会遇到一种让人摸不着头脑的情况:明明在后台传个大安装包或者大图,页面转了半天直接报错,或者点完提交后表单里的内容像蒸发了一样全没了。遇到这类上传和数据提交故障,往往不是代码写崩了,而是前台看门的 Nginx 和后门干活的 PHP 在“体量限制”上没对齐,暗中闹了别扭。

谁在拦路:看状态码和表单表现

排查的第一步,其实是看故障发生在哪道关卡。Nginx 相当于小区的门卫,PHP 则是真正进屋办事的工人。

如果大文件刚提交,浏览器直接甩出一个 413 Request Entity Too Large 错误,这说明请求根本就没走到 PHP 那一步。Nginx 在门口看了一眼请求体积,发现超过了自己配置里的设定,直接把请求拦截下来了。这时候翻看 Nginx 的错误日志,往往能直接印证拦截记录。

要是没有看到 413 报错,而是文件传不上去,或者长表单提交后后台数据库里对应字段全空、连上传的文件数组也丢了,那问题大概率已经漏进了 PHP。在处理机制中,当请求体超过了 post_max_size 时,PHP 不仅会拒绝这笔数据,还会直接把接收到的数据全部清空丢弃,前端连个明确报错都看不到,只留下莫名其妙的“空数据”。

顺藤摸瓜:核对两端配置链条

理清了现象,排查的重点就落在两套环境的参数对账上。从外到内,整条链路必须是逐级放宽或匹配的,任何一处短板都会卡死流程。

Nginx 这端主要看 client_max_body_size 这个指令。如果它设置得比 PHP 允许的额度还要小,那 PHP 无论怎么放权都没用,大体积请求在网关层就会被无情截断。

而顺着链路走到 PHP 内部,还得排查三个紧密咬合的关键项:upload_max_filesize、post_max_size 和 memory_limit。这里存在严格的大小关系约束:内存限制 memory_limit 得管得住整个脚本运行,所以通常要大于等于 post_max_size;而允许的 POST 请求体总大小 post_max_size,又必须大于等于单文件上传限制 upload_max_filesize。

避开覆盖坑:找准真正生效的配置

不少人排查时最容易踩的坑,就是以为改了配置文件就万事大吉。有人在命令行直接敲命令查配置,查出来的其实是 CLI 命令行环境的参数,和跑在网站后台的 PHP-FPM 完全是两码事。

更隐蔽的问题出在配置生效层级上。有些系统在全局配置文件之外,还在 PHP-FPM 的专属 Pool 配置(比如 www.conf)里通过 php_admin_value 硬编码了参数。这种设置的优先级极高,会直接压制全局修改。排查时如果只盯准主配置文件,很容易出现“明明改大了数值,重启后依旧卡死”的怪现象。

顺着链路看,先用错误状态区分是 Nginx 拦了还是 PHP 扔了,再按顺序校对 Nginx 与 PHP 内部的层级数值,最后确认改动的配置确实在运行态生效,体量限制不匹配的毛病基本就能理清楚了。

参与讨论

1 条评论
  • 那年夏天

    413这个报错太常见了,每次先查它