解決nginx下載大文件出現文件損壞,文件大小不一致

小夥伴今天反饋了一個問題,說,網頁上傳了一個2MB的文件,在網頁下載時,只有64KB,而且打開失敗。確認該BUG確實存在且必現後,我,踏上了調試解決此BUG之路。php

一、系統是nginx+php+MySQL,憑經驗判斷與mysql無關,能夠無視TA。 
二、從PHP網頁上傳2MB文件後,直接在服務器打開該文件,能夠正常查閱,而且與原文件二進制同樣。 
三、用不一樣瀏覽器,不一樣電腦反覆從PHP網頁下載該文件,發現下載的文件均只有64KB。 
四、換一個體積只有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文件夾,因此沒法獲得正常的文件,因而,爲該文件夾賦上權限後,問題解決。mysql

回頭看,這究竟是什麼緣由呢?nginx

查看nginx配置文件,能夠找到下面這一段: 
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文件的時候,須要用到臨時文件夾進行緩衝,而這裏沒有權限操做,就致使了該問題。sql

相關文章
相關標籤/搜索