1. 程式人生 > >centos nginx代理無返回值的問題

centos nginx代理無返回值的問題

今天跟前端除錯的時候發現,在使用者登入的一系列請求中,有一個請求沒有返回值,開始的時候認為是程式碼邏輯出錯,但單獨除錯程式碼發現功能沒有問題,然後就懷疑是否是nginx攔截掉了返回值,故而在nginx中加入列印返回值的功能

一.安裝列印返回值外掛

1.安裝openresty

nginx不具有列印返回值的功能,需借用openresty實現,官網也是如此推薦的:https://www.nginx.com/resources/wiki/modules/lua/

按照官網步驟安裝即可:http://openresty.org/cn/linux-packages.html

shell > sudo yum install yum-utils
shell > sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
shell > sudo yum -y install openresty

2.修改nginx 配置

在openresty安裝目錄下集成了nginx,直接修改其下的nginx.conf配置

shell > vim /usr/local/openresty/nginx/conf/nginx.conf
http {
    include       mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$resp_body"';

    access_log  logs/access.log main;

    server {
        listen 80;
        server_name 10.130.161.42;
        set $resp_body "";
        location ^~ /hotpot-dev/ {
          lua_need_request_body on;
            body_filter_by_lua '
                local resp_body = string.sub(ngx.arg[1], 1, 1000)
                ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body
                if ngx.arg[2] then
                    ngx.var.resp_body = ngx.ctx.buffered
                end
            ';
        }

    }
}

啟動nginx

/usr/local/openresty/nginx/sbin/nginx -c /usr/local/openresty/nginx/conf/nginx.conf

二.檢視nginx access.log

通過檢視access.log發現,沒有返回值的請求,log格式如下:

10.130.161.63 - - [16/Oct/2018:11:43:54 +0800] "POST /test-dev/protocol?uid=10000232833 HTTP/1.1" 499 0 "https://apps-123.apps.fbsbx.com/instant-bundle/123/123/index.html?psev=1&source=fbinstant-123&IsMobileWeb=0" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0" "-" ""

最後一列為"",表示沒有返回資訊,http狀態碼為499,通過網路查詢,發現http狀態碼499代表客戶端與服務端斷開了連線,可以通過配置proxy_ignore_client_abort解決,具體配置如下:

location ^~ /hotpot-dev/ {
          proxy_pass   http://testDev;
          proxy_ignore_client_abort   on;
	}

重新nginx,發現問題仍然沒有解決,檢視access.log,發現已經有返回值了,由此可以推斷前端也斷開發連線,故此接收不到返回值,而之所以會出現http 499這個狀態碼,是由於瞬間同一個使用者有大量的請求連線到nginx,導致nginx主動斷開了連線,proxy_ignore_client_abort,客戶端主動斷掉連線之後,Nginx 會等待後端伺服器處理完(或者超時),然後記錄“後端的返回資訊”到日誌,但不推薦使用這個引數,因為這樣當有大量瞬間斷開的請求時,後端會默默地全部處理,比較浪費資源,而且併發壓力比較大時,用這種方法將壓垮機器,而且使用這個引數後,客戶端仍然處於斷開狀態,無法從根本上解決問題

之後與前端確認了其確實是在同一幀傳送了多個請求到伺服器,導致的nginx與客戶端連線中斷,當前端改為前一個請求處理完成後再發送下一個請求時,這個問題得以解決