服务器上传文件出现500异常,但是其他不涉及文件的接口均正常

服务器上传文件出现500错误,但是其他不涉及文件的接口均正常

出现的情景描述:

1.有用户报告说注册无法成功,经过前端的盘查发现实在注册的时候必须调用的上传文件的接口A抛出500错误,但不是每次都抛出不过有很大几率抛出500.

2.A接口接受5个参数和一个文件multi类型,至传递前5个参数能够请求到代码,但是传入文件之后不是500错误就是很长时间超时。

3.重启nginx无效,问题依旧。重启fpm无效,问题依旧。

4.机器很久没有启动过了top显示内存占用较高于是重启机器。重启机器问题消失,A接口正常工作,15分钟后再次出现问题且症状依旧。

5.nginx日志没有写任何东西进去,看不到具体错误log(别喷楼主不配log目录,是配了的。。。。它就是没写。。权限也是给了的,这个是最为头疼的地方,不怕问题就怕问题没有头绪)

6.ali云控制台显示cpu负载很低,网络占用很低,磁盘占用很低(以后大家还是信命令行吧,aliyun也不怎么靠谱,后面会讲到)

第一步,于是开始找问题,先是怀疑是否是上传文件缓冲区大小的问题,于是借鉴 http://www.aslibra.com/blog/read.php?1620 的方法更改的nginx的缓冲区的配置。以使得程序不报500错误,顺利运行程序的目的。

第二步,经过如是修改程序已经可以运行,但是接口调用总是返回文件上传错误,错误码为7(nginx日志仍旧没有任何更多的记录,最后一条记录是重启之后写入的)。error=7代表UPLOAD_ERR_CANT_WRITE这个常量,也就是说文件的临时目录写入失败。于是楼主就将nginx的client_body_temp_path重新指定了位置,权限更改为755,问题依旧,改为777,问题依旧。

第三部,现在看来问题似乎陷入了僵局,没有日志,没有临时文件,开放了权限,增加了缓冲区大小,还是不行。但是,正如时间会给我们答案一样,对于一个技术人,外网会给我们答案(内网的东西都shi的很,最后发现是个巨简单的问题。)。连上google搜索一下error=7 upload_err_cant_write立刻得到了答案那就是————df -h看看?我靠,磁盘占用100%,aliyun居然都没有报警,反而显示的占用很低。f××k!

第四步,既然找到了问题所在那肯定是要解决的,因为tmp文件并不长期保存,所以tmp目录也不大也就几百M,于是使用一个比较常用的查看文件夹的命令 du -hsx * | sort -rh | head -10,从/目录找起,最后竟然发现再源文件目录高达9个G,天哪我有那么伟大么,,写了9G的代码?那为毛工资还没有很高。。。。。别慌继续往下找,就发现问题处在thinkphp的runtime目录下的logs中,哈哈问题找到了,原来tp在默认情况下是要写日志的,而且增量还非常快,基本上每秒几kb。遂删除tp日志,再配置文件中关闭日志写入即可。

附:

楼主一开始还想到了增加fpm子进程数量,这里顺便提一下

1.根据php加载的扩展的多少fpm worker的内存占用大概是在20M~50M之间,如何分配,到底该分配多少子进程就是一个学问。如果本机不跑其他的东西那大可以将子进程设置为使用一半的内存,数量自己除,然后再之后的使用过程中根据cpu的负载等等进行一些细节调整。

2.如果本机需要部署一些其他的服务,比如楼主的这台2核 8G 20G 5M的aliyun centOS上就部署了比较多的服务,列举一下gearman、mysql、redis、nginx、fpm、还有楼主自己写的apns推送、tomcat、openfire、还有一个给openfire做前端负载均衡的java小程序、还有的就不列举了穷人就是这么任命。并且文件上传还要走这台机器,可以说平时负载还是有的,但不是太大,访问接口的人也不多因此可以用200M到500M来服务fpm是可以接受的,峰值情况下1G也是可以接收的,因此pm.max_chindren = 20;pm.start_servers = 10;pm.min_spare_servers = 1;//这个是动态最小设置要小于start_server pm.max_spare_servers=15;//这个是动态最小设置,要大于start_servers

3.nginx的进程数量我也修改了一下,数量修改为cpu的1~1.5倍比较合适,毕竟机器上已经有其它的服务了。

 

好了,就这么个简单的问题折磨了我几个小时,也算是吃一堑涨一智吧。

作者:sunyuw

链接:http://www.cnblogs.com/sunyuw/p/4207740.html

欢迎转载,但请注明并带上本博问文的原文链接和我的名字,谢谢。