出現的情景描述:
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
歡迎轉載,但請注明並帶上本博問文的原文鏈接和我的名字,謝謝。
