歡迎光臨
每天分享高質量文章

Nginx 學習 —— 負載均衡

點擊上方“芋道原始碼”,選擇“置頂公眾號”

技術文章第一時間送達!

原始碼精品專欄

 

來源:http://t.cn/RDXvzld

說到負載均衡,我想說它天生就是不公平的。為什麼這麼說呢?請你想象這麼一個場景,一塊蛋糕切成5份,現在要將它分給A、B、C3個人,基於公平原則,我們說每個人正常可以分到5/3份,但是,5/3份很明顯不好進行劃分,誒碰巧這個時候A中午沒有吃飯,能多吃幾份,B、C肚子偏飽,1份即可,基於不公平原則,我們分給A3份蛋糕,B、C個一份,這樣按照一定策略將資源進行劃分的方式,是一種均衡的策略。

在web應用中,一個web應用(或者說某個服務)在生產環境中一般是集群部署,然後採用負載均衡硬體(F5)或者軟體(nginx)將請求分發到不同的服務主機中進行處理,很明顯,這裡的蛋糕就相當於我們的web request,假設有5個request進來,基於一定的均衡策略,我們可能會將其中的3個request交給A服務器去處理,B、C服務器各處理1個request。下麵我畫張圖片簡單說明這個模型:

那麼使用負載均衡有什麼好處呢?首先優化資源利用率,最大化吞吐量,減少延遲,再者系統的伸縮性和可靠性也得到了相應的保障。

一、Nginx 負載均衡及相關策略介紹

負載均衡技術少不了相關的均衡策略,Nginx 中提供了 4 種均衡策略,我們可以根據具體的業務場景選擇合適的均衡策略。下麵分別介紹這 4 中均衡策略:

  • 1、基於輪詢的均衡策略:

    輪詢嘛,就是說對進到nginx的request按照遍歷的方式進行分發,如果request 1 分發到 Server A,那麼request 2將被分發到 Server B,……以此迴圈類推

  • 2、基於最少連接數的均衡策略:

    最少連接,也就是說nginx會判斷後端集群服務器中哪個Server當前的 Active Connection 數是最少的,那麼對於每個新進來的request,nginx將該request分發給對應的Server.

  • 3、基於ip-hash的均衡策略:

    我們都知道,每個請求的客戶端都有相應的ip地址,該均衡策略中,nginx將會根據相應的hash函式,對每個請求的ip作為關鍵字,得到的hash值將會決定將請求分發給相應Server進行處理

  • 4、基於加權輪詢的均衡策略:

    加權輪詢,很顯然這個策略跟我們開題引入的場景是一樣的,nginx會給Server配置相應的權重,權重越大,接收的request數將會越多

上面的均衡策略其實都非常很好理解,但是如果想瞭解其實現原理,可以看原始碼,但是小編就算了,我是看不懂C、C++的。

二、Nginx 不同均衡策略的配置介紹

  • 1、基於輪詢的均衡策略:

這個是Nginx預設的均衡演算法,如果你不進行相關的配置,預設會執行該策略,配置如下:

http {
   upstream myapp1 {
       server srv1.example.com;
       server srv2.example.com;
       server srv3.example.com;
   }
   server {
       listen 80;

       location / {
           proxy_pass http://myapp1;
       }
   }
}

可以看出,nginx負載均衡使用到的指令不多,其中比較重要的兩個是upstreamproxy_pass,upstream塊定義一個後端小集群,裡邊配置相關的Server組成這個集群,同時upstream為這個集群起個相應的名字,本實體叫myapp1.proxy_pass處於location塊中,表示對於所有符合/的request,將會交給哪個集群進行處理,本實體為http://myapp1

但又一點我們需要註意,上面http://myapp1myapp1必須是upstream起的名字,對於協議是使用http還是https,都無所謂,如果你的協議使用https,則將http直接改成https即可。另外,如果你在upstream中的server指令中指定了協議名,那麼在proxy_pass指令中就不需要加上協議名稱了。

nginx負載均衡使用反向代理實現,也就是我們上面使用到的proxy_pass指令,支持的協議不止是httphttps,同時還支持FastCGIuwsgiSCGImemcachedgRPC,如果你需要使用除了httphttps外的其他協議,我們不能使用proxy_pass指令了,應該轉而使用相應的指令,如fastcgi_passuwsgi_passscgi_passmemcached_passgrpc_pass

該策略處理負載,小編認為還是有缺陷的,不能防止某台Server出現負載過高的情況。因為如果有些請求執行時間過長,而系統的併發量卻非常大,那麼就可能導致某台Server出現request堆積,負載過高,snowslide is possible~

  • 2、基於最少連接數的均衡策略:

該策略主要使用了least_conn指令,具體配置如下:

 upstream myapp1 {
   least_conn;
   server srv1.example.com;
   server srv2.example.com;
   server srv3.example.com;
}

該策略還是比較人性化的,可以按照機器的實際情況進行剛需分配。

  • 3、基於ip-hash的均衡策略:

當然了,如果我們想實現這樣一個功能,我們想讓對於相同客戶端的請求每次都被分發到同一個Server進行處理,上面兩種策略都是不做到。此策略可確保來自同一客戶端的請求始終定向到同一服務器,但此服務器不可用時除外。相關配置如下:

upstream myapp1 {
   ip_hash;
   server srv1.example.com;
   server srv2.example.com;
   server srv3.example.com;
}

既然相同客戶端的請求能被同一臺Server進行處理,那麼相同客戶端的會話Session就可以實現持久化了。

  • 4、基於加權輪詢的均衡策略:

基於加權輪詢的策略就不需要過多講解了,就是在輪詢的基礎上加上個權重信息

upstream myapp1 {
   server srv1.example.com weight=3;
   server srv2.example.com;
   server srv3.example.com;
}

這種策略適合Server機器處理能力有區別的情況。

三、nginx 負載均衡更多高級特性及配置

  • 1、健康檢查

    不僅人需要體檢,機器也是需要體檢的,那麼就當nginx就是那位體檢醫生吧!nginx健康檢查是什麼呢?當我們一個request進來被分發到相應的Server進行處理後,nginx會檢查該request執行是否超時,是否執行失敗了等情況,然後做出相應的處理—比如說當nginx檢查出Server A執行某request時報出502錯誤了,那麼下次nginx負載均衡時就會在upstream塊中將Server A排除掉,不分發請求給到Server A了。

    對於健康檢查的功能,nginx提供了基本兩個指令,即max_failsfail_timeout,也就是說當nginx檢查到某Server發生錯誤的request數達到max_fails或者執行某request執行時間超過fail_timeout了,如果發生超時了,nginx將開始使用實時請求優雅地探測Server,如果有響應,則認為對應的Server還是活著的,沒有毛病的。

  • 2、更多配置

    針對上面upstream塊中的server指令,其格式為:server address [parameters];,裡邊的parameters可以有很多的引數型別,比如說指定某台Server不參與負載均衡等。具體配置詳見官網鏈接,點擊此處傳送門




如果你對 Dubbo / Netty 等等原始碼與原理感興趣,歡迎加入我的知識星球一起交流。長按下方二維碼噢

目前在知識星球更新了《Dubbo 原始碼解析》目錄如下:

01. 除錯環境搭建
02. 專案結構一覽
03. 配置 Configuration
04. 核心流程一覽

05. 拓展機制 SPI

06. 執行緒池

07. 服務暴露 Export

08. 服務取用 Refer

09. 註冊中心 Registry

10. 動態編譯 Compile

11. 動態代理 Proxy

12. 服務呼叫 Invoke

13. 呼叫特性 

14. 過濾器 Filter

15. NIO 服務器

16. P2P 服務器

17. HTTP 服務器

18. 序列化 Serialization

19. 集群容錯 Cluster

20. 優雅停機

21. 日誌適配

22. 狀態檢查

23. 監控中心 Monitor

24. 管理中心 Admin

25. 運維命令 QOS

26. 鏈路追蹤 Tracing

… 一共 69+ 篇

目前在知識星球更新了《Netty 原始碼解析》目錄如下:

01. 除錯環境搭建
02. NIO 基礎
03. Netty 簡介
04. 啟動 Bootstrap

05. 事件輪詢 EventLoop

06. 通道管道 ChannelPipeline

07. 通道 Channel

08. 位元組緩衝區 ByteBuf

09. 通道處理器 ChannelHandler

10. 編解碼 Codec

11. 工具類 Util

… 一共 61+ 篇

目前在知識星球更新了《資料庫物體設計》目錄如下:


01. 商品模塊
02. 交易模塊
03. 營銷模塊
04. 公用模塊

… 一共 17+ 篇

原始碼不易↓↓↓

點贊支持老艿艿↓↓

赞(0)

分享創造快樂