1629. 按鍵持續時間最長的鍵
1114
2022-05-30
前面的時候,我們講解了nginx的負載均衡的配置,還有常見的一些策略
那他有沒有一些更深入的東西我們可以掌握,且在實際工作中是非常有用的?
肯定是有的,那我們現在就通過一些案例背景,來進一步學習Nginx更多核心知識。
Nginx探測后端節點可用性
下面這一個是我們很常見的負載均衡的配置,但里面有兩個參數,我們需要重點去掌握先。
upstream lbs { server 192.168.0.106:8080 max_fails=2 fail_timeout=60s ; server 192.168.0.106:8081 max_fails=2 fail_timeout=60s; }
max_fails和fail_timeout這兩個參數有什么意思呢?我們來詳細的給他講解這兩個參數的作用以及強大之處。
假如請求分發到IP1這個節點,但是IP1這個節點已經掛了,那后續有其他請求,是不是還會繼續分配給IP1這個節點呢?這個max_fails的配置就是表示允許某一個節點失敗的次數,默認為1,當超過最大次數時就不會請求
那這個ip1節點沒有分配流量,它是長時間都不會分配流量了嗎?假如我這個節點又恢復正常之后,那是應該合理的給他分配一些流量。所以fail_timeout 這個配置,就表示在max_fails 次失敗之后暫停分配流量的時間,默認是10秒。
綜合起來解釋:max_fails=N 設定Nginx與后端節點通信的嘗試失敗的次數,在fail_timeout參數定義的時間內,如果失敗的次數達到此值,Nginx就認為這個節點不可用,在下一個fail_timeout時間段到來前,服務器不會再被嘗試分配流量。如果設為0就會停止統計嘗試次數,認為服務器是一直可用的。
那具體什么是nginx認為的失敗呢,可以通過指令proxy_next_upstream來配置什么是失敗的嘗試。
這又是我們另外一個很常見的一個坑以及技能,下面再進一步去講一下我們這個配置的使用。
但有個點先注意下:默認配置時,http_404狀態不被認為是失敗的嘗試。
互聯網公司基本架構都是如下圖所示 (排除其他硬件負載均衡、流量清洗等組件)
整個鏈路基本都要考慮高可用,避免單點故障,先不說如何架構整個系統,
流量入口是Nginx, 再到業務網關或者公共網關,再到業務服務器,最后到數據庫。
這邊剖析幾個實際工作中遇到的問題 和 團隊小伙伴在生產環境犯的錯誤(其他公司里面的P0和P1事故)
先說幾個場景:
場景一:由于你的重啟部署,測試人員正在測試一個復雜項目,突然服務不可用;
再或者應用上線,生產環境啟動不成功或者啟動耗時久,導致線上接口成功率下降嚴重。
場景二: 為了解決上述的問題,前端或者后端進行了應用接口探測和請求重試,由于部分接口是新人開發沒做好接口冪等性處理,導致業務數據故障。
在敏捷開發和持續交付盛行的時代,作為開發人員,在項目開發尾聲或者進入提測階段的時候,會把項目部署到測試環境,然后由測試人員進行測試。
稍微有點規模的公司都是有多套環境,用于應對不同場景,比如阿里、騰訊等這些大廠,應用開發上線的流程基本都 開發人員在開發環境驗證好后,項目部署到測試環境發提測郵件,測試人員在測試環境測試,沒問題后進入預發布環境,最后到上線到灰度或者生產環境。
看起來是不是很nice沒問題?如果項目周期短,那開發和測試人員肯定會接觸特別頻繁,誰寫的代碼敢保證一定沒有bug呢?
所以在提測階段,測試人員發現了bug,反饋給開發人員進行修復,修復后又部署到測試環境;
由于開發人員的重新部署項目到測試環境,測試人員在測試一個重大功能或者復雜流程的時候,突然接口出現不可訪問或者5XX錯誤,出現一兩次可以忍受,但是頻繁出現,測試人員就會提著40米的大刀來找開發人員,這個肯定是影響項目進度的。
且多數公司包括大廠,在測試環境的服務器配置比較差,且一個項目也不會分配太多服務器資源,所以部署啟動又很耗時,復雜項目啟動花個幾分鐘到十多分鐘都是存在的,特別是項目周期短且急的情況下。
那怎么解決這個問題呢?
測試環境由測試人員進行部署,但往往應用部署需要有依賴上下文,比如數據庫更新,配置文件更新,RPC接口更新,這些交給測試人員進行的話多少會有點難度,所以一般還是開發人員部署。
采用無感知部署和業務重試,這個思想也類似應用優雅上下線,總體流程是這樣的:
一個請求到后端服務器,如果接口不可用或者出現特定的錯誤,比如5XX等,就把請求轉發到另外一個應用節點,直到請求成功(也可以設置一定的轉發次數)
那上述這個就可以解決由于重啟應用導致接口不可用的問題,做到了無感知部署,但是也并非全部都是無感知的,先繼續往下看。
那應該怎么做呢,有沒啥開源的中間件可以解決我這個問題呢?
Nginx就可以解決你的這個問題,里面有個負載均衡模塊upstream,里面最少配置兩個后端應用節點
光這樣就可以了嗎?其實不是的,Nginx怎么知道你說的請求不可用是什么意思呢,認定標準是什么嗎,
比如接口超時、服務不可用、Http狀態碼404、5XX錯誤等等,這些都是有問題的請求,肯定是可以指定的,所以你還需要配置下面這個指令?proxy_next_upstream
upstream lbs { server 192.168.0.106:8080 max_fails=2 fail_timeout=60s ; server 192.168.0.106:8081 max_fails=2 fail_timeout=60s; } location /api/ { proxy_pass http://lbs; proxy_next_upstream error timeout http_500 http_503 http_404; }
可定制化才是最厲害的,如果業務認為http狀態碼404不需要轉發,那把這個http_404去除即可。
所以使用了上述配置,如果你重啟了某個節點,那測試人員是不是可以依舊正常進行測試了,假如請求分發到你重啟的那個應用,請求失敗后依舊會被轉發到其他節點。
對應生成環境也是,如果某個服務器接口掛了,配置了重試策略,這個就可以做到自動轉發請求,?接口容災?,除非全部節點都不可用。
一切都是那么如意,采用了上述的配置后,接口成功率也提高了,加入原先的時候是95%, 現在變成98%了。
但是,看問題別想的那么簡單,業務故障的坑就來了。
接口重試一定要和業務互相配合,包括遠程RPC調用,只要是涉及到數據的新增、修改、刪除操作,你是否有考慮冪等性呢?盡管你有考慮,但是你能保證團隊里面每個人都一直有重視這個問題不?
雖然有些同學會說 公司會做CodeReview代碼審查,但誰能保證每次都可以全部審查完,包括很大廠也是沒把這個工作落實好。
故障例子:?好比你做了一個話費充值項目或者發送驗證碼的接口,一般會涉及到第三方接口調用,是很容易報錯或者超時的。
由于沒做接口冪等性處理,接口重試會造成業務數據重復增加,比如老王充值了50元,由于接口沒做冪等性處理,被轉發了好幾遍,那最終這個就是公司的資損了,如果再經過“羊毛黨”規模化,造成的損失就大了。
盡管前端、后端代碼 是沒做請求重試,但是Nginx那么做了轉發重試,最終釀成了業務故障。
所以Nginx這邊的重試配置,上述默認只會對GET請求進行重試,其他的POST、PATCH等對數據有修改的請求是不進行重試的。
有興趣的可以看下官方文檔:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream
如果你想提高接口成功率,一定需要Nginx幫你做重試,那你需要做好接口冪等性處理, ?然后在Nginx那邊增加這個指令參數?non_idempotent
所以凡事有利也有弊,一定要細心,好比算法里面強調的,“時間和空間”,應該用時間換空間,還是空間換時間,還是兩個取中間,沒有絕對的事情,一定要和業務實際情況進行選擇。
上面講解了很多個例子,如果大家想實際操作那就可以按照下面這兩個步驟進行驗證。
暫停一個后節點,然后訪問接口大于10次,Nginx會把這個節點剔除
重啟這個節點,在fail_timeout周期里面不會再獲取流量
upstream lbs { server 192.168.0.106:8080 max_fails=10 fail_timeout=20s ; server 192.168.0.106:8081 max_fails=10 fail_timeout=20s; } location /api/ { proxy_pass http://lbs; proxy_next_upstream error timeout http_500 http_503 http_404; }
本章小結
掌握Nginx的fail_timeout 和 max_fails的使用
掌握Nginx的?proxy_next_upstream?的使用
Nginx
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。