小夥伴今天回饋了一個問題,說,網頁上傳了一個2MB的文件,在網頁下載時,只有64KB,並且打開失敗。確認該BUG確實存在且必現後,我,踏上了調試解決此BUG之路。
1、系統是nginx+php+mysql,經驗判斷與mysql無關,可以無視TA。
2.從PHP網頁上傳2MB文件後,直接在伺服器開啟該文件,可以正常查閱,並且與原文件二進位一樣。
3.用不同瀏覽器,不同電腦重複從PHP網頁下載文件,發現下載的文件皆只有64KB。
4.換一個體積只有90KB的文件,從PHP網頁上傳下載,均無異常。
通過以上4點,基本上可以判定,問題出在nginx。這時候,打開nginx的日誌文件,發現如下錯誤log,
[crit] 21636#0: *843968 open() “/home/www/local/nginx/fastcgi_temp/0/11/0000000110” failed (13: Permission denied) while reading upstream,…
可以大膽猜測,由於沒有足夠權限操作fastcgi_temp資料夾,所以無法得到正常的文件,於是,為該資料夾賦上權限後,問題解決。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
**fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;**
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
每次下載失敗時檔案的大小總是64KB,應該跟這裡有關。原來,nginx會使用fastcgi_buffer_size指定的大小的緩衝區用來快取fastcgi流的內容。當大小超出此大小時會繼續以fastcgi_buffers指定的數量和大小申請緩衝區。如果依然超出此大小,會將多餘的內容寫入暫存檔案。也就是說,在本情況下,nginx首先會使用一個64K的緩衝區緩衝fastcgi流的第一部分,超出後最多申請4*64K=256K的緩衝區用於緩衝。如果繼續超出,則寫入臨時檔案。所以,在下載大於256K檔案的時候,需要用到臨時資料夾進行緩衝,而這裡沒有權限操作,就導致了這個問題。