[temp]Nginx 錯誤502 upstream sent too big header while reading response header from upstream

Nginx 502 Bad Gateway的含義是請求的PHP-CGI已經執行,但是由於某種原因(一般是讀取資源的問題)沒有執行完畢而導致PHP-CGI進程終止。
Nginx 504 Gateway Time-out的含義是所請求的網關沒有請求到,簡單來說就是沒有請求到可以執行的PHP-CGI。
解決這兩個問題其實是需要綜合思考的,一般來說Nginx 502 Bad Gateway和php-fpm.conf的設置有關,而Nginx 504 Gateway Time-out則是與nginx.conf的設置有關。
1.查看FastCGI進程是否已經啓動
NGINX 502錯誤的含義是sock、端口沒被監聽造成的。我們先檢查fastcgi是否在運行
2.檢查系統Fastcgi進程運行情況
除了第一種情況,fastcgi進程數不夠用、php執行時間長、或者是php-cgi進程死掉也可能造成nginx的502錯誤
運行以下命令判斷是否接近FastCGI進程,如果fastcgi進程數接近配置文件中設置的數值,表明worker進程數設置太少
netstat -anpo | grep "php-cgi" | wc -l
3.FastCGI執行時間過長
根據實際情況調高以下參數值
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
4.頭部太大這種情況可能是由於nginx默認的fastcgi進程響應的緩衝區太小造成的, 這將導致fastcgi進程被掛起, 如果你的fastcgi服務對這個掛起處理的不好, 那麼最後就極有可能導致504 Gateway Time-out
現在的網站, 尤其某些論壇有大量的回覆和很多內容的, 一個頁面甚至有幾百K
默認的fastcgi進程響應的緩衝區是8K, 我們可以設置大點:                          

fastcgi_buffer_size 128k; 
fastcgi_buffers 8 128k;  
如果你使用的是nginx的負載均衡Proxying,調整

http{
proxy_buffer_size  16k;    # proxy_buffer_size 1024k
proxy_buffers   4 16k;   #  proxy_buffers   4 2048k

....

}
5.https轉發配置錯誤
正確的配置方法
server_name www.xok.la;
location /myproj/repos {
set $fixed_destination $http_destination;
if ( $http_destination ~* ^https(.*)$ )
{
set $fixed_destination http$1;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Destination $fixed_destination;
proxy_pass http://subversion_hosts;
}
下面我們來仔細分析一下php-fpm.conf幾個重要的參數:
php-fpm.conf有兩個至關重要的參數,一個是”max_children”,另一個是”request_terminate_timeout”
我的兩個設置的值一個是”40″,一個是”900″,但是這個值不是通用的,而是需要自己計算的。
計算的方式如下:
如果你的服務器性能足夠好,且寬帶資源足夠充足,PHP腳本沒有系循環或BUG的話你可以直接將”request_terminate_timeout” 設置成0s。0s的含義是讓PHP-CGI一直執行下去而沒有時間限制。而如果你做不到這一點,也就是說你的PHP-CGI可能出現某個BUG,或者你的 寬帶不夠充足或者其他的原因導致你的PHP-CGI能夠假死那麼就建議你給”request_terminate_timeout”賦一個值,這個值可以 根據你服務器的性能進行設定。一般來說性能越好你可以設置越高,20分鐘-30分鐘都可以。由於我的服務器PHP腳本需要長時間運行,有的可能會超過10 分鐘因此我設置了900秒,這樣不會導致PHP-CGI死掉而出現502 Bad gateway這個錯誤。
而”max_children”這個值又是怎麼計算出來的呢?這個值原則上是越大越好,php-cgi的進程多了就會處理的很快,排隊的請求就會很 少。設置”max_children”也需要根據服務器的性能進行設定,一般來說一臺服務器正常情況下每一個php-cgi所耗費的內存在20M左右,因 此我的”max_children”我設置成40個,20M*40=800M也就是說在峯值的時候所有PHP-CGI所耗內存在800M以內,低於我的有 效內存1Gb。而如果我的”max_children”設置的較小,比如5-10個,那麼php-cgi就會“很累”,處理速度也很慢,等待的時間也較 長。如果長時間沒有得到處理的請求就會出現504 Gateway Time-out這個錯誤,而正在處理的很累的那幾個php-cgi如果遇到了問題就會出現502 Bad gateway這個錯誤。


一個實例:
http://www.levil.cn/post/29/
我在CentOS下配置lnmp組合基本上用的都是同樣的配置文件,一直都沒出現過問題,可最近在一個vps上安裝同樣的環境之後,網站在線10多人就出 現了打開速度非常緩慢的情況,有好幾次都是直接達到了nginx中設置的腳本最大超時時間300秒,結果導致nginx往客戶端瀏覽器發送了一個504 Gateway Time-out的錯誤代碼,分析了之後改動了幾處配置文件,終於避免了該情況的出現。


從 錯誤代碼基本可以確定跟nginx本身無關,主要是提交給php-fpm的請求未能正確反饋而導致,一般情況下,提交動態請求的時候,nginx會直接把 請求轉交給php-fpm,而php-fpm再分配php-cgi進程來處理相關的請求,之後再依次返回,最後由nginx把結果反饋給客戶端瀏覽器,但 我這個vps目前跑的是個純php應用內容,實際上用戶所有的請求都是php請求,有的耗費時間比較久,php-cgi進程就一直都被用滿,而php- fpm本身的配置文件只打開了10組php-cgi進程,這樣的話在線用戶稍微多的話就會導致請求無法被正常處理而出錯。


大概分析出了原因,下面做就比較容易了,首先是更改php-fpm的幾處配置:


把max_children由之前的10改爲現在的30,這樣就可以保證有充足的php-cgi進程可以被使用;
把request_terminate_timeout由之前的0s改爲60s,這樣php-cgi進程處理腳本的超時時間就是60秒,可以防止進程都被掛起,提高利用效率。


接着再更改nginx的幾個配置項,減少FastCGI的請求次數,儘量維持buffers不變:


fastcgi_buffers由 4 64k 改爲 2 256k;
fastcgi_buffer_size由 64k 改爲 128K;
fastcgi_busy_buffers_size 由 128K 改爲 256K;
fastcgi_temp_file_write_size 由 128K 改爲 256K。


好了,重新加載php-fpm和nginx的配置,再次測試,至今兩週時間內沒有再出現504 Gateway Time-out的情況,算是達到效果了。


另一例子:
使用ie正常.其他人用FF也正常.但是有個人使用FF瀏覽報錯502
查看後臺error日誌,發現一句
upstream sent too big header while reading response header from upstream
就是反饋回來的頭部信息太大
一般應該是cookie裏面帶的
懷疑是FF裏面的某個插件引起返回太多的頭部信息
一個個排查.最後發現是FireBug導致的
既然是fastcgi返回的頭部太大.應該可以配置
查找資料後發現應該是和fastcgi_buffer_*有關的
將相關配置增大.發現問題解決
這邊使用的是
fastcgi_buffer_size 32k;
fastcgi_buffers 8 32k;
比原來的默認4k/8k要大許多


 
http400錯:
nginx的HTTP400錯誤,而且這個HTTP400錯誤並不是每次都會出現的,查了一下發現nginx 400錯誤是由於request header過大,通常是由於cookie中寫入了較長的字符串所引起的。解決方法是不要在cookie裏記錄過多數據,如果實在需要的話可以考慮調整在nginx.conf中的client_header_buffer_size(默認1k)
若cookie太大,可能還需要調整large_client_header_buffers(默認4k),該參數說明如下:
請求行如果超過buffer,就會報HTTP 414錯誤(URI Too Long)
nginx接受最長的HTTP頭部大小必須比其中一個buffer大,否則就會報400的HTTP錯誤(Bad Request)。


 
http413錯:
在上傳時nginx返回了413錯誤,查看log文件,顯示的錯誤信息是:”413 Request Entity Too Large”, 於是在網上找了下“nginx 413錯誤”發現需要做以下設置:
在nginx.conf增加client_max_body_size的設置, 這個值默認是1m,可以增加到8m以增加提高文件大小限制;
如果運行的是php,那麼還要檢查php.ini,這個大小client_max_body_size要和php.ini中的如下值的最大值一致或者稍大,這樣就不會因爲提交數據大小不一致出現的錯誤。
post_max_size = 8M
upload_max_filesize = 2M

 

年底了事情真多,club服務器有問必答 提交頁面 提交出這個問題
The page you are looking for is temporarily unavailable.Please try again later.
一看就知道是nginx的請求的錯誤,,惆悵啊。。
就開啓了 錯誤日誌查看。。。
tail -f error.log
就具體錯誤是 :
upstream sent too big header while reading response header from upstream
我們是nginx反向代理
proxy是nginx作爲client轉發時使用的,如果header過大,超出了默認的1k,就會引發上述的upstream sent too big header (說白了就是nginx把外部請求給後端apache ,apache返回的header  太大nginx處理不過來就導致了。
 
  server {
        listen       80;
        server_name  *.xywy.com ;
        large_client_header_buffers 4 16k;
        #charset koi8-r;
        # access_log off;
        location / {
#添加這3行 ,
                proxy_buffer_size 64k;
                proxy_buffers   32 32k;
                proxy_busy_buffers_size 128k;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP       $remote_addr;
           proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
           set $baiduspider '';
           if ( $http_user_agent ~ Baiduspider) {
              set $baiduspider Baidu;
          }
............
 
 如果是 nginx+PHPcgi 就該 
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on
011/01/07 11:12:57 [error] 10770#0: *38585340 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 116.22.131.154, server: *.xywy.com, request: "GET /ysmp/index.php?did=124994 HTTP/1.0", upstream: "http://127.0.0.1:8080/ysmp/index.php?did=124994", host: "xywy.yn16.com"
後來原來那錯誤沒了出了新錯誤了 upstream timed out 超時?
server {
        listen       80;
        server_name  *.xywy.com ;
  large_client_header_buffers 4 16k;
        client_max_body_size 300m;
        client_body_buffer_size 128k;
        proxy_connect_timeout 600;
        proxy_read_timeout 600;
        proxy_send_timeout 600;
                proxy_buffer_size 64k;
                proxy_buffers   4 32k;
                proxy_busy_buffers_size 64k;
                proxy_temp_file_write_size 64k;
        #charset koi8-r;


        # access_log off;
後來參數我又改了下 就好了。。。
 可以參考:


http://wiki.nginx.org/NginxHttpProxyModule
http://blog.sina.com.cn/s/blog_5dc960cd0100i4mt.html

 

cookies的值超出了範圍我是說

看看了一下日誌

錯誤502 upstream sent too big header while reading response header from upstream

 

sudo gedit /var/log/nginx/error.log

查看錯誤日誌

 

 

upstream sent too big header while reading response header from upstream

你去搜這個錯誤,網上的解釋都差不多,無外乎是cookie攜帶的header太多了,讓你設置:

fastcgi_buffer_size 128k;
fastcgi_buffers 8 128k;

逐步嘗試。其中fastcgi_buffers 8 128k 這句,fastcgi_buffers 32 32k 這樣更好,內存是整塊分配和釋放的,減少單位k數能儘可能利用。

另外,如果你用nginx做負載均衡的話,改了上述參數是沒用的,要在轉發的配置上,比如以下設置:

 

location @to_other {

                proxy_buffer_size  128k;

                proxy_buffers   32 32k;

                proxy_busy_buffers_size 128k;

                add_header X-Static transfer;

                proxy_redirect off;

                proxy_set_header Host $host;

                proxy_set_header X-Real-IP  $remote_addr;

                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                proxy_pass http://backend;    #請求轉發

        }

加粗的三行纔會起作用。

fastcgi_* 可以理解成nginx接受client請求時的響應使用的。proxy是nginx作爲client轉發時使用的,如果header過大,超出了默認的1k,就會引發上述的upstream sent too big header。

可以參考:

http://wiki.nginx.org/NginxHttpProxyModule

http://blog.sina.com.cn/s/blog_5dc960cd0100i4mt.html

其它搜索結果可以無視,都是大同小異的。

location ~ \.php$ {

       fastcgi_buffer_size 128k;

       fastcgi_buffers 32 32k;

       include /etc/nginx/fastcgi_params;

       fastcgi_pass   127.0.0.1:9000;

       fastcgi_index index.php;

       fastcgi_param SCRIPT_FILENAME /host/web/$fastcgi_script_name;

    }

 

如題,最近網站頻繁出現502錯誤,簡直無法正常運轉,出現這種情況大多是php-cgi超時沒有返回信息,或進程僵死等情況造成的。我們的nginx已經配置到極致這些都已經老早做過修改了,但現在又出然出現。
經過分析將nginx的error log打開,發現”pstream sent too big header while reading response header from upstream”這樣的錯誤提示,查閱了一下資料,大意是nginx緩衝區有一個bug造成的,我們網站的頁面消耗佔用緩衝區可能過大。參考老外寫的修改辦法增加了緩衝區容量大小設置,502問題徹底解決,後來系統管理員又對參數做了調整隻保留了2個設置參數:client head buffer,fastcgi buffer size。

 

參考:代

http://www. sudone .com/nginx/nginx_400_bad_request.html
http://blog. rackcorp .com/?p=14

二、昨天裝上nginx後在高負載的時候,論壇上傳圖片或者執行較長時間腳本的時候就不停的出現502 Bad Gateway ,網上搜了,大多數都是張大師的那篇解決方案,他的解決方案是

 

http 
{
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
}

 

增加了fastcgi的相應請求時間。但是我在實際中碰到了這個問題,設置到500,還是會出現,只是比我設置120的時候要少一些。後來發現主要是在一些post或者數據庫操作的時候出現這種情況,靜態頁面是不會出現的

 

反覆的查問題,調試,也加大了CGI的進程數。
務器,ip查詢,手機號,proxy,天氣預報,火車時刻,身份證號碼,飛機航班,新華字典查詢等  S6 b4 \) y& c( \! j) ]
256再加上去可能會變得很慢。佔用內存大了。123cha.com1 u& }. p1 [7 b% L/ \0 \
在php-fpm.conf設置中還有一項,可能當時沒注意到,無意中改了這個值。
request_terminate_timeout
這個值是max_execution_time,就是fast-cgi的執行腳本時間。
0s 123cha.com* S( v, U9 D5 q6 T; i* z6 u- R
0s爲關閉,就是無限執行下去。(當時裝的時候沒仔細看就改了一個數字)
發現,問題解決了,執行很長時間也不會出錯了。
優化fastcgi中,還可以改改這個值5s 。看看效果
終於發現502的錯誤其實不是nginx的問題,
php-cgi進程數不夠用、php執行時間長、或者是php-cgi進程死掉,都會出現502錯誤

三、
一臺服務器上運行着nginx php(fpm) xcache,訪問量日均 300W pv左右

最近經常會出現這樣的情況: php頁面打開很慢,cpu使用率突然降至很低,系統負載突然升至很高,查看網卡的流量,也會發現突然降到了很低。這種情況只持續數秒鐘就恢復了
檢查php-fpm的日誌文件發現了一些線索

 

在這幾句的前面,是1000多行的關閉children和開啓children的日誌
原來,php-fpm有一個參數 max_requests ,該參數指明瞭,每個children最多處理多少個請求後便會被關閉,默認的設置是500。因爲php是把請求輪詢給每個children,在大流量下,每個childre到達max_requests所用的時間都差不多,這樣就造成所有的children基本上在同一時間被關閉。
在這期間,nginx無法將php文件轉交給php-fpm處理,所以cpu會降至很低(不用處理php,更不用執行sql),而負載會升至很高(關閉和開啓children、nginx等待php-fpm),網卡流量也降至很低(nginx無法生成數據傳輸給客戶端)) O" ], O  w$ q/ v1 X* D
解決問題很簡單,增加children的數量,並且將 max_requests 設置未 0 或者一個比較大的值,重啓php-fpm

四、
nginx 502錯誤的原因比較多,是因爲在代理模式下後端服務器出現問題引起的。這些錯誤一般都不是nginx本身的問題,一定要從後端找原因!但nginx把這些出錯都攬在自己身上了,着實讓nginx的推廣者備受置疑,畢竟從字眼上理解,bad gateway?不就是bad nginx嗎?讓不瞭解的人看到,會直接把責任推在nginx身上,希望nginx下一個版本會把出錯提示寫稍微友好一些,至少不會是現在簡單的一句502 Bad Gateway,另外還不忘附上自己的大名。
502錯誤最通常的出現情況就是後端主機當機,當然還有。在upstream配置裏有這麼一項配置:proxy_next_upstream,這個配置指定了nginx在從一個後端主機取數據遇到何種錯誤時會轉到下一個後端主機,裏頭寫上的就是會出現502的所有情況拉,默認是error timeout,error就是當機、斷線之類的,timeout就是讀取堵塞超時,比較容易理解。我一般是全寫上的:
proxy_next_upstream error timeout invalid_header http_500 http_503;
不過現在可能我要去掉http_500這一項了,http_500指定後端返回500錯誤時會轉一個主機,後端的jsp出錯的話,本來會打印一堆stacktrace的錯誤信息,現在被502取代了。但公司的程序員可不這麼認爲,他們認定是nginx出現了錯誤,我實在沒空跟他們解釋502的原理了……
invalid_header我也沒認真查清到底指的什麼,我也很想先把它弄下來
503錯誤就可以保留,因爲後端通常是apache resin,如果apache死機就是error,但resin死機,僅僅是503,所以還是有必要保留的

昨日,有朋友問我,他將Web服務器換成Nginx 0.6.31  + PHP 4.4.7(FastCGI)後,有時候訪問會出現“502 Bad Gateway”錯誤,如何解決。

  我讓按照以下兩個步驟去解決,最後在第2步中將FastCGI的timeout時間增加爲300,問題解決:

  PS:比較羨慕迅雷的Web服務器,16G內存。



  1、查看當前的PHP FastCGI進程數是否夠用:

netstat -anpo | grep "php-cgi" | wc -l


  如果實際使用的“FastCGI進程數”接近預設的“FastCGI進程數”,那麼,說明“FastCGI進程數”不夠用,需要增大。



  2、部分PHP程序的執行時間超過了Nginx的等待時間,可以適當增加nginx.conf配置文件中FastCGI的timeout時間,例如:

......
http 
{
......
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
......
}
......

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章