做服务器运维的人大概率都碰到过这个场景禅道上传一个附件几MB的PDF都传不上去界面弹一句“文件太大”或者干脆给你一个413页面。一开始我还以为是禅道的问题到处找后台设置后来才发现禅道跑在Linux上文档上传大小这件事根本不是单个环节说了算而是浏览器、Web服务器、PHP解释器、禅道自身四层配置共同卡出来的结果。这篇就按我在Linux服务器上实际排查和修改的顺序把禅道文档上传限制这件事从头到尾讲透顺便把那些文档里不常写、但现场一定会踩的坑也一起列出来。1. 禅道的上传限制到底卡在哪几层1.1 一条上传请求要经过的完整链路先别急着改参数得先知道文件从浏览器进入禅道中间要过几道关卡。你点“上传附件”那一刻文件先被POST到Web服务器如果是典型的LNMP环境就是Nginx先接收到请求接着Nginx把请求转给PHP-FPM进程PHP解释器开始处理处理完之后PHP再把数据交给禅道自身的业务逻辑禅道根据它的内部配置决定这个文件能不能收。只要这个链路里任何一环说“不行”你的文件就传不上去。而且每一层报错的方式都不一样Nginx不开心直接吐一个413页面PHP配置不够可能提示“超出upload_max_filesize”禅道自己的限制没放开就算PHP和Nginx都放行了系统依然会提示“文件过大”。很多同学改完PHP配置发现没有效果多半就是只改了一层其他层还在挡路。1.2 各层默认值与排查定位技巧下面是这个链路里最常见的几个限制点我把它们整理成了一个表方便你对照排查限制层关键参数默认值本地一般表现Web服务器-Nginxclient_max_body_size1M直接413 Request Entity Too LargeWeb服务器-ApacheLimitRequestBody0不限制超出后返回403PHPupload_max_filesize2M“文件超出 upload_max_filesize 限制”PHPpost_max_size8M整个表单无法提交指数组/空数据PHPmax_execution_time30秒大文件上传到一半502/504超时PHPmemory_limit128M图片处理/缩略图时内存溢出禅道自身上传附件大小配置版本不同常见几十M后台明确提示“文件过大”一个非常实用的排障思路先别猜是哪一层看报错。如果是Nginx 413直接把Nginx配置改了如果是PHP的报错英文提示改php.ini如果禅道自己提示文件过大那一定是禅道内部配置的问题。沿着报错去定位比盲目改参数快得多。2. Linux下定位并修改PHP上传参数2.1 先搞清楚Web服务真正加载的是哪份php.ini很多人修改PHP上传限制的第一步就翻车了——打开了一个php.ini改完也确认了Web服务一重启没效果。原因往往是你改的那份php.ini根本不是Web服务在用的那份。Linux下PHP经常同时存在CLI和PHP-FPM两套运行环境Debian/Ubuntu系更是把配置文件拆得清清楚楚CLI用的是/etc/php/7.4/cli/php.iniFPM用的是/etc/php/7.4/fpm/php.ini。如果禅道跑在NginxPHP-FPM下而你改的是CLI那份那改再多也没用。所以第一步一定是先确认当前Web环境加载的是哪个配置文件。在禅道根目录下临时放一个phpinfo.php文件内容就一行?php phpinfo();然后在浏览器访问这个文件搜索“Loaded Configuration File”看到的那份php.ini才是真正生效的文件。用完之后记得立刻把它删掉别留安全隐患。如果你倾向于用命令查也可以这样php --ini php -i | grep Loaded Configuration File但这里有个坑命令查到的通常是CLI的配置和Web走的FPM配置可能不是同一份。所以我建议验证upload_max_filesize这类参数时优先用phpinfo()页面来看这才是你Web服务真实加载的那套配置。2.2 核心参数怎么改数值、关系与备份定位到正确的php.ini之后修改的核心参数主要是一组我通常是一起调的避免改了一个另一个又成为瓶颈upload_max_filesize 200M post_max_size 300M max_execution_time 600 max_input_time 600 memory_limit 512M这里面有一个很多人不理解的关系为什么post_max_size要比upload_max_filesize大因为upload_max_filesize管的是“单个文件”的上限而post_max_size管的是“整个POST请求体”的上限。文件本身只是请求的一部分请求里还要带上表单字段、文件描述信息等。你设的单文件上限是200M但整个请求体如果还是默认的8M那一个5M的文件也传不上去。一般我会给post_max_size留出三分之一的余量比如文件限制200Mpost_max_size至少设250到300M。用一个生活化的类比upload_max_filesize是单个包裹的限重post_max_size是这次快递车上所有包裹的总限重车上如果连一个包裹的重量都装不下那这个包裹肯定发不出去。max_execution_time和memory_limit也要一起看。大文件上传时PHP脚本的执行时间可能超过默认的30秒一旦超时就容易出现502或者上传中断内存限制太小禅道上传图片后生成缩略图时可能直接内存耗尽报错。改之前养成备份的习惯这个习惯能救你很多次cp php.ini php.ini.bak改完之后重启PHP-FPM让配置生效systemctl restart php7.4-fpm不同环境命令有差异有的叫php-fpm有的带版本号源码编译安装的可以用/etc/init.d/php-fpm restart。总之改完配置一定记得要重启解析器不是只重启Nginx就够了。这个细节我后来专门验证过只reload nginxPHP配置不会生效必须重启PHP-FPM服务才行。3. Nginx/Apache的请求体大小限制3.1 Nginx的client_max_body_sizeNginx的默认client_max_body_size是1M这意味着只要文件超过1M可能还没到PHP层面Nginx就直接给你拦下来了。这也是为什么很多人改完PHP配置后上传大文件依然失败因为请求在Nginx这一层就被拒了报错信息通常是“413 Request Entity Too Large”。修改Nginx配置的方法是在Nginx配置文件的http、server或location层级中加上一行client_max_body_size 300m;我一般建议放在server块里针对禅道所在的站点单独放开而不是全局放开。原因很简单全局放开意味着这台服务器上所有站点都能传大文件攻击者往任何站点塞大文件都畅通无阻风险敞口太大。只对禅道这个站放行其他站点保持默认安全边界就清晰很多。如果你明确知道这台服务器上只有禅道一个站点也可以放在http层省事。改完Nginx配置一定要先检查配置文件的语法别直接reload否则语法错误会导致Nginx起不来整个站点直接挂掉nginx -t systemctl reload nginxnginx -t通过之后再reload基本就不会出问题。还有一层容易忽略如果你用的是Nginx代理PHP-FPM并且fastcgi_read_timeout设置得比较小上传大文件时可能遇到504 Gateway Timeout。这个参数控制的是Nginx等待PHP-FPM响应的超时时间建议调大一些比如fastcgi_read_timeout 600s;这个参数可以在server或location里和client_max_body_size放在一起。之前处理过禅道传视频文件失败的问题客户端明明网络没问题但每次传到一半就504就是fastcgi_read_timeout默认60秒撑不住大文件传输。3.2 Apache的LimitRequestBody如果你的禅道跑在LAMP环境Apache PHP下对应的限制是LimitRequestBody。这个参数默认是00的意思是不限制但有些安全基线配置模板会把它显式设成一个小值那样就需要调整。修改方法是在Apache的Directory或VirtualHost配置段里调整单位是字节Directory /var/www/html LimitRequestBody 314572800 /Directory这里的314572800就是300M对应的字节数。改完重启或重载Apachesystemctl reload apache2CentOS系的httpd服务名可能不一样用systemctl reload httpd。4. 禅道自身的上传限制设置与生效验证4.1 在禅道后台/源码中找上传限制配置很多人把PHP和Nginx都改好了结果禅道后台上传大文件还是提示“文件过大”这时候就该看禅道自身的配置了。禅道没有完全依赖PHP的upload_max_filesize它内部还有一个附件大小的限制不同版本这个配置的位置和写法有差别有的在后台“系统”或“自定义”菜单里有的需要直接看源码文件。我的建议是先在禅道后台找有没有“附件大小”“上传限制”之类的设置项把它调大保存。如果后台找不到对应选项再考虑从源码或数据库角度查。禅道很多版本的附件大小限制存在数据库的zt_config表中比如搜索和“上传”或“文件”相关的配置记录SELECT * FROM zt_config WHERE key LIKE %file% OR key LIKE %upload%;还有一种通用方法直接去禅道源码目录里搜关键字比如grep -rn maxFileSize /opt/zbox/app/zentao/禅道安装路径不同命令里的路径按你实际情况改。搜出来以后就能看到默认值在哪里定义以及具体的处理逻辑。这里要特别提醒直接改数据库或源码里的配置属于兜底方案操作前一定要备份原值和原文件避免版本升级时配置被覆盖导致问题。总体优先级是能通过后台界面改的就用后台改后台没有才去考虑源码和数据库层面。后台改最安全也最不容易在升级时被覆盖。4.2 全链路生效验证配置改完怎么知道真的生效了光看配置文件里的数字不算数要实测。我一般分三步验证第一步用phpinfo()页面确认PHP层面的参数已经变成修改后的值。这一步能排除“改错php.ini”或者“没重启PHP-FPM”的问题。第二步在禅道里实际上传一个符合新限制大小的文件。比如原来限制是2M我把限制调到了200M那就传一个50M左右的压缩包测试一下。别只传一个刚好超过旧限制的文件那只能证明旧限制失效了不能证明新限制稳定可用。第三步故意传一个超过当前限制的大文件确认它会正常被拦截而不是请求卡死。这个测试能验证限制是起作用的避免出现“限制形同虚设”的情况。验证过程中如果还报错留意报错特征413是Nginx层英文PHP warning是php.ini层禅道自己的“文件过大”是内部配置层。按这个特征快速定位是哪一层还在拦截逐层解决就行。5. 常见问题与避坑经验5.1 高频问题速查现象大概率原因排查/解决办法改了php.ini上传还是失败改错了文件或PHP-FPM没重启用phpinfo()确认实际加载的配置文件路径执行systemctl restart php-fpm上传大文件直接413Nginx的client_max_body_size没调或改错层检查server块加上client_max_body_size并reload上传到一半504fastcgi_read_timeout或max_execution_time不够Nginx增加fastcgi_read_timeoutPHP增加max_execution_time禅道后台仍提示文件过大禅道自身的附件大小配置没改后台找上传配置或查zt_config表/源码中的maxFileSize图片上传成功但缩略图生成失败PHP的memory_limit不足调大memory_limit一般256M以上比较稳上传后POST的数据是空的表单提交无反应post_max_size比upload_max_filesize小让post_max_size大于upload_max_filesize留出余量多站点服务器改了global配置其他站点也受影响client_max_body_size放在了http层建议改到server层只对禅道站点生效修改Nginx后服务起不来配置语法错误先用nginx -t检查语法5.2 现场实操中积累的几个心得先说一个最典型的“连环坑”我之前处理过一次禅道上传限制的问题PHP配置改了Nginx配置也改了后台一看禅道自身上限还是默认的。当时团队传的是几十MB的产品录屏总觉得是网络问题。后来把禅道内部的上传限制也找出来调大再配合配置好的PHP和Nginx参数才真正解决。这个案例说明四层配置是一个整体漏了哪一层都会让你觉得“明明改了却没效果”。再提醒一个细节Linux下很多环境同时存在多套PHP比如系统自带的PHP和源码编译的PHP可能同时存在。排查时如果发现phpinfo()里显示的版本和PHP-FPM跑的不是一个版本那多半是同时装了两套PHP配置文件的路径也自然不同。这时候要按PHP-FPM实际用的版本去改不要看到一个php.ini就改。还有一个容易被忽略的安全上别把限制调得过于夸张。比如给禅道设置1G甚至更大的上传限制看起来方便实际上风险很大。恶意用户可以通过上传超大文件来消耗服务器磁盘和带宽这是在给服务器埋雷。一般来说按团队实际业务场景设置就够比如传文档和录屏的团队调到100M到200M就足够日常使用了。如果真有超大文件交换需求我更倾向于走对象存储或单独的文件服务而不是无脑放宽Web上传限制。最后说一下排查思路的沉淀遇到“上传不了”的问题不要急着改参数先按链路拆解再确认报错在哪一层最后定位改哪里的配置。这个思路不止适用于禅道也适用于所有基于PHP的Web应用比如其他开源系统、自建网盘等。工具会变链路逻辑不会变。