標籤:

nginx的proxy_next_upstream使用中的一個坑

nginx的proxy_next_upstream使用中的一個坑

來自專欄 突破技術邊界

今天線上系統出了點問題,機房的電信出口突然不通了,原本以為能自動切換的nginx配置,居然沒有生效,導致了業務告警,手工緊急處理了才解決了。

當時的設想是,如果這個服務的訪問,出現了500或者超時的情況,會自動重試到下一個伺服器去,採用的是nginx的proxy_next_upstream, 配置大概如下:

upstream example_upstream{ server 192.168.0.1 max_fails=1 fail_timeout=30s; server 192.168.0.2 max_fails=1 fail_timeout=30s backup;}location /example/ { proxy_pass http://example_upstream/; proxy_set_header Host: test.example.com; proxy_set_head X-real-ip $remote_addr; proxy_next_upstream error timeout http_500;}

按照設想,如果192.168.0.1這台伺服器返回了超時或者500,那麼訪問 /example/ 時應該會自動重試到下一台伺服器去,即到192.168.0.2去。

但是情況並沒有發生,於是造成了業務故障。

事後我使用openresty,寫了些簡單的hello world來測試nginx的這個proxy_next_upstream, 完全沒有問題呀,可是線上的這個服務就是不行,真的想砸了電腦的心都有了。

在公司反反覆複試驗了幾十次,快到晚上十點才下班回家。回家路上突然想到一種可能,興奮得想趕緊回到家試驗試驗。然而到家後試驗,並未成功,甚是失望。又反反覆複試驗了一個小時,總是失敗。

然後重新看文檔,Module ngx_http_proxy_module ,走投無路,只能逐字逐句看文檔了,突然看到這麼一段:

這段在公司查找的時候就看到了,但是對non-idempotent 這個單詞,我不認識,然後想當然的理解為某個意思,於是就沒有去認真看完這段話,覺得和問題沒有關係。

把這個配置加進去,變成: proxy_next_upstream error timeout http_500 non_idemponent; 問題終於解決了。

這段話的意思是說,像 post, lock, patch 這種會對伺服器造成不冪等的方法,默認是不進行重試的,如果一定要進行重試,則要加上這個配置。

至於為什麼我用openresty寫的試驗會成功,而線上的這個服務一直失敗的原因,實則是因為我試驗的介面是GET訪問的,而線上的服務是POST訪問的。

之所以今天會出現這個故障,也是因為線上系統最近升級了nginx,如上圖所示,這個配置是 1.9.13版本之後才有的。

以後還是要仔細認真讀官方文檔啊

推薦閱讀:

為什麼要執行多個進程,把所有功能都放到一個進程裡面執行會影響性能嗎?
[轉載]Nginx防蜘蛛爬蟲處理
有哪些知名網站Web伺服器是Nginx?
Kong - The Microservice API Gateway

TAG:Nginx |