首頁>技術>

常見的nginx訪問架構

nginx經常被用來做生產的代理和負載均衡,它高效的處理能力,得到了很多公司的青睞。可是,隨著業務的不斷髮展,隨之而來,可能會因為nginx產生一些意想不到的問題,比如說幽冥請求。

本文所說的幽冥請求泛指以下幾種情況:

一次客戶端請求,前端能夠收到返回的資訊,但是後端位於不同VM的同個程式卻被請求了多次,請求引數完全一致,並全部執行正常一次客戶端請求,前端報異常返回,但是後端位於不同VM的同個程式被請求多次,從業務日誌角度排查,程式返回正常客戶端上傳請求,出現一次上傳了多個同樣檔案的情況

所謂的幽冥請求,其實就是本不該出現卻又出現的請求。這裡限定情況為明確客戶端確實請求了一次的情況下。

在遇到過的幽冥請求案例中,大部分情況,程式上線後執行正常,經過了長時間未更改程式碼的執行後,突然就發生了幽冥請求情況。幽冥請求可能一直出現,也可能偶爾出現。透過nginx日誌,可以確認來自客戶端的請求只有一次,可是請求返回的時間較長。透過程式日誌確定,請求正常可達,並且有正常的返回。事件發生後程序員都是沒法從本地或者測試環境進行重現的。

問題究竟在哪呢?其實,問題出現在nginx的原生模組ngx_http_proxy_module配置上。對於ngx_http_proxy_module,其實大部分使用過的技術人員應該都不預設,它主要實現的是反向代理的功能,常用的配置如下:

 location / {        expires -1;        proxy_http_version 1.1;        proxy_set_header Connection "";        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://$UPSTREAM_NAME;    }

可是,它有另外的幾個配置卻被忽略了:

proxy_send_timeout	360;//預設60,單位sproxy_connect_timeout	360;//預設60,單位sproxy_read_timeout	360;//預設60,單位sproxy_next_upstream	error timeout;

以上幾個配置,主要用於故障轉移,當nginx將請求轉發到對應伺服器,但後期認為服務相應異常時,便會觸發故障轉移,其中各個配置解釋如下:

Syntax:     proxy_read_timeout time;Default:    proxy_read_timeout 60s;Context:    http, server, location定義從代理伺服器讀取響應的超時。Syntax:     proxy_connect_timeout time;Default:    proxy_connect_timeout 60s;Context:    http, server, location定義與代理伺服器建立連線的超時。Syntax:     proxy_send_timeout time;Default:    proxy_send_timeout 60s;Context:    http, server, location設定將請求傳輸到代理伺服器的超時。Syntax:     proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | non_idempotent | off ...;Default:    proxy_next_upstream error timeout;Context:    http, server, location指定在何種情況下一個失敗的請求應該被髮送到下一臺後端伺服器其中:error 和後端伺服器建立連線時,或者向後端伺服器傳送請求時,或者從後端伺服器接收響應頭時,出現錯誤timeout 和後端伺服器建立連線時,或者向後端伺服器傳送請求時,或者從後端伺服器接收響應頭時,出現超時invalid_header 後端伺服器返回空響應或者非法響應頭http_500 後端伺服器返回的響應狀態碼為500http_502 後端伺服器返回的響應狀態碼為502http_503 後端伺服器返回的響應狀態碼為503http_504 後端伺服器返回的響應狀態碼為504http_404 後端伺服器返回的響應狀態碼為404off 停止將請求傳送給下一臺後端伺服器

重新回到幽冥請求上,大部分的情況,nginx配置了全域性超時時間,為了方便各個業務,可能會設定的比較大,如5分鐘,然而卻沒有配置代理超時時間,預設使用為60s。

請求過程

這種情況在客戶端看來,請求只請求了一次,除了反應慢一點沒有任何異常。在nginx的請求日誌看來,客戶端的請求只有一次。而程式看來,雖然處理時間較長,可是前一次請求確實正常返回結果了,而第二次請求,卻像是憑空產生的一般。

其實,在排查的過程中,不難發現,重複請求產生的時間是有規律的,由於nginx代理超時時間為60s,所以重複請求產生的時間,應該是在上一輪請求之後的60s後。根據這樣的規律,便不難查出原因了。

總結,遇到上述問題的時候,為保生產,應該第一時間將代理過期時間設定為合理的區間,保證生產正常執行。但是,一個介面的請求時長過程,本身也算是一種潛在的問題,應該及時最佳化解決。將代理過期時間設長,應該事用在大檔案上傳或者一些實在無法避免的問題上。

17
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 拒絕在CentOS上被割韭菜,是時候轉向更穩定的Linux了