當前位置:
首頁 > 最新 > Nginx 用得好,這個知識點最重要!

Nginx 用得好,這個知識點最重要!

1LSGO軟體技術團隊

貢獻人:LSGO船長

如果喜歡這裡的內容,你能夠給我最大的幫助就是轉發,告訴你的朋友,鼓勵他們一起來學習。

If you like the content here, the greatest helpyou can give meis forwarding, so tell your friends and encourage them to learn together.

很多人都知道nginx可以做反向代理和負載均衡,但是關於nginx的健康檢查(health_check)機制了解的不多。

其實社區版nginx提供的health_check機制其實很薄弱,主要是通過在upstream中配置max_fails和fail_timeout來實現,這邊文章主要是深入分析社區版的health_check機制。

當然還有更好的一些建議,比如商業版的nginx plus或者阿里的tengine,他們包含的健康檢查機制更加完善和高效,如果你堅持使用nginx社區版,當然還可以自己寫或者找第三方模塊來編譯了。

首先說下我的測試環境,CentOS release 6.4 (Final) + nginx_1.6.0 + 2台tomcat8.0.15作為後端伺服器。(聲明:以下所有配置僅僅為測試所用,不代表線上環境真實所用,真正的線上環境需要更多配置和優化。)

nginx配置如下:

#user nobody;

worker_processes1;

#pid logs/nginx.pid;

events{

worker_connections1024;

}

http{

includemime.types;

default_typeapplication/octet-stream;

log_formatmain"$remote_addr-$remote_user[$time_local] "$request" "

"$status$body_bytes_sent"$http_referer" "

""$http_user_agent" "$http_x_forwarded_for""

access_log logs/access.log main;

sendfileon;

keepalive_timeout65;

upstreambackend {

serverlocalhost:9090max_fails=1fail_timeout=40s;

serverlocalhost:9191max_fails=1fail_timeout=40s;

}

server{

listen80;

server_namelocalhost;

location/ {

proxy_passhttp://backend;

proxy_connect_timeout1;

proxy_read_timeout1;

}

error_page500502503504/50x.html;

location= /50x.html {

roothtml;

}

}

}

關於nginx和tomcat的配置的基本配置不再說明,大家可以去看官方文檔。

我們可以看到我在upstream 指令中配置了兩台server,每台server都設置了max_fails和fail_timeout值。

現在開始啟動nginx,然後啟動後台的2台server, 故意把在Tomcat Listener中Sleep 10分鐘,也就是tomcat啟動要花費10分鐘左右,埠已開,但是沒有接收請求,然後我們訪問http://localhost/response/ (response這個介面是我在tomcat中寫的一個servlet介面,功能很簡單,如果是9090的server接收請求則返回9090,如果是9191埠的server則返回9191.),現在觀察nginx的表現。

我們查看nginx中


192.168.42.254- - [29/Dec/2014:11:24:23+0800]"GET /response/ HTTP/1.1"504537720380"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36"2.004host:health.iflytek.com

192.168.42.254- - [29/Dec/2014:11:24:24+0800]"GET /favicon.ico HTTP/1.1"502537715311"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36"0.000host:health.iflytek.com


2014/12/2911:24:22[error]6318#: *4785892017upstream timed out (110: Connection timed out)whilereading response header from upstream, client:192.168.42.254, server: health.iflytek.com, request:"GET /response/ HTTP/1.1", upstream:"http://192.168.42.249:9090/response/", host:"health.iflytek.com"

2014/12/2911:24:23[error]6318#: *4785892017upstream timed out (110: Connection timed out)whilereading response header from upstream, client:192.168.42.254, server: health.iflytek.com, request:"GET /response/ HTTP/1.1", upstream:"http://192.168.42.249:9191/response/", host:"health.iflytek.com"

2014/12/2911:24:24[error]6318#: *4785892017nolive upstreamswhileconnectingtoupstream, client:192.168.42.254, server: health.iflytek.com, request:"GET /favicon.ico HTTP/1.1", upstream:"http://health/favicon.ico", host:"health.iflytek.com"

(為什麼要在listener中設置睡眠10分鐘,這是因為我們的業務中需要做緩存預熱,所以這10分鐘就是模擬伺服器啟動過程中有10分鐘的不可用。)

觀察日誌發現在兩台tomcat啟動過程中,發送一次請求,nginx會自動幫我們進行重試所有的後端伺服器,最後會報 no live upstreams while connecting to upstream錯誤。這也算是nginx做health_check的一種方式。這裡需要特彆強調一點,我們設置了proxy_read_timeout 為 1秒。後面再重點講解這個參數,很重要。

等待40s,現在把9090這台伺服器啟動完成,但是9191這台伺服器仍然是正在啟動,觀察nginx日誌表現。

access.log

192.168.42.254- - [29/Dec/2014:11:54:18+0800]"GET /response/ HTTP/1.1"20019194423"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36"0.210host:health.iflytek.com

192.168.42.254- - [29/Dec/2014:11:54:18+0800]"GET /favicon.ico HTTP/1.1"404453674311"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36"0.212host:health.iflytek.com


$

沒有列印任何錯誤

瀏覽器返回9090,說明nginx正常接收請求。

我們再次請求一次。


192.168.42.254- - [29/Dec/2014:13:43:13+0800]"GET /response/ HTTP/1.1"20019194423"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36"1.005host:health.iflytek.com

說明正常返回,同時返回9090

error.log

2014/12/2913:43:13[error]6323#: *4801368618upstream timed out (110: Connection timed out)whilereading response header from upstream, client:192.168.42.254, server: health.iflytek.com, request:"GET /response/ HTTP/1.1", upstream:"http://192.168.42.249:9191/response/", host:"health.iflytek.com"

發現nginx error.log 增加了一行upstream time out的錯誤。但是客戶端仍然正常返回,upstream默認是輪訓的負載,所以這個請求默認會轉發到9191這台機器,但是因為9191正在啟動,所以這次請求失敗,然後有nginx重試轉發到9090機器上面。

OK,但是fail_timeout=40s是什麼意思呢?我們要不要重現一下這個參數的重要性?

Let"s go !

現在你只需要靜靜的做個美男子,等待9191機器啟動完畢!多發送幾次請求!然後咦,你發現9191機器返回9191

響應了噢!fail_timeout=40s其實就是如果上次請求發現9191無法正常返回,那麼有40s的時間該server會不可用,但是一旦超過40s請求也會再次轉發到該server上的,不管該server到底有沒有真正的恢復。

所以可見nginx社區版的health_check機制有多麼的薄弱啊,也就是一個延時屏蔽而已,如此周而復始!

如果你用過nginx plus其實你會發現nginx plus 提供的health_check機制更加強大,說幾個關鍵詞,你們自己去查! zone slow_start health_check match ! 這個slow_start其實就很好的解決了緩存預熱的問題,比如nginx發現一台機器重啟了,那麼會等待slow_starts設定的時間才會再次發送請求到該伺服器上,這就給緩存預熱提供了時間。

來源:運維部落

聲明:推送內容及圖片來源於網路,部分內容會有所改動,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯繫我們刪除或授權事宜。

經過8年多的發展,LSGO軟體技術團隊在地理信息系統、數據統計分析、計算機視覺領域積累了豐富的研發經驗,也建立了人才培養的完備體系。

歡迎對演算法設計與實現感興趣的同學加入,與我們共同成長進步。

本微信公眾平台長期系統化提供有關機器學習、軟體研發、教育及學習方法、數學建模的知識,並將以上知識轉化為實踐。拒絕知識碎片化、耐心打磨技能、解決實際問題是我們的宗旨和追求。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 LSGO軟體技術團隊 的精彩文章:

TAG:LSGO軟體技術團隊 |