分散式系統關註點——僅需這一篇,吃透「負載均衡」妥妥的

来源:https://www.cnblogs.com/Zachary-Fan/archive/2018/10/08/LoadBalance.html
-Advertisement-
Play Games

本文長度為3426字,預計讀完需1.2MB流量,建議閱讀9分鐘。 閱讀目錄 「負載均衡」是什麼? 常用「負載均衡」策略圖解 常用「負載均衡」策略優缺點和適用場景 用「健康探測」來保障高可用 結語 「負載均衡」是什麼? 常用「負載均衡」策略圖解 常用「負載均衡」策略優缺點和適用場景 用「健康探測」來保 ...


本文長度為3426字,預計讀完需1.2MB流量,建議閱讀9分鐘。

 

閱讀目錄

 

 

  上一篇《分散式系統關註點——初識「高可用」》我們對「高可用」有了一個初步認識,其中認為「負載均衡」是「高可用」的核心工作。那麼,本篇將通過圖文並茂的方式,來描述出每一種負載均衡策略的完整樣貌。

 

 

一、「負載均衡」是什麼

        正如題圖所示的這樣,由一個獨立的統一入口來收斂流量,再做二次分發的過程就是「負載均衡」,它的本質和「分散式系統」一樣,是「分治」。

 

        如果大家習慣了開車的時候用一些導航軟體,我們會發現,導航軟體的推薦路線方案會有一個數量的上限,比如3條、5條。因此,其實本質上它也起到了一個類似「負載均衡」的作用,因為如果只能取Top3的通暢路線,自然擁堵嚴重的路線就無法推薦給你了,使得車流的壓力被分攤到了相對空閑的路線上。

 

        在軟體系統中也是一樣的道理,為了避免流量分攤不均,造成局部節點負載過大(如CPU吃緊等),所以引入一個獨立的統一入口來做類似上面的“導航”的工作。但是,軟體系統中的「負載均衡」與導航的不同在於,導航是一個柔性策略,最終還是需要使用者做選擇,而前者則不同。

 

        怎麼均衡的背後是策略在起作用,而策略的背後是由某些演算法或者說邏輯來組成的。比如,導航中的演算法屬於「路徑規劃」範疇,在這個範疇內又細分為「靜態路徑規劃」和「動態路徑規劃」,並且,在不同的分支下還有各種具體計算的演算法實現,如Dijikstra、A*等。同樣的,在軟體系統中的負載均衡,也有很多演算法或者說邏輯在支撐著這些策略,巧的是也有靜態和動態之分。

 

 

二、常用「負載均衡」策略圖解

        下麵來羅列一下日常工作中最常見的5種策略。

 

01  輪詢

 

  這是最常用也最簡單策略,平均分配,人人都有、一人一次。大致的代碼如下。

 

int  globalIndex = 0;   //註意是全局變數,不是局部變數。

try
{

    return servers[globalIndex];
}
finally
{
    globalIndex++;
    if (globalIndex == 3)
        globalIndex = 0;
}

 

02  加權輪詢

        在輪詢的基礎上,增加了一個權重的概念。權重是一個泛化後的概念,可以用任意方式來體現,本質上是一個能者多勞思想。比如,可以根據宿主的性能差異配置不同的權重。大致的代碼如下。

 

int matchedIndex = -1;
int total = 0;
for (int i = 0; i < servers.Length; i++) { servers[i].cur_weight += servers[i].weight;//①每次迴圈的時候做自增(步長=權重值) total += servers[i].weight;//②將每個節點的權重值累加到彙總值中 if (matchedIndex == -1 || servers[matchedIndex].cur_weight < servers[i].cur_weight) //③如果 當前節點的自增數 > 當前待返回節點的自增數,則覆蓋。 { matchedIndex = i; } } servers[matchedIndex].cur_weight -= total;//④被選取的節點減去②的彙總值,以降低下一次被選舉時的初始權重值。 return servers[matchedIndex];

 

        這段代碼的過程如下圖的表格。"()"中的數字就是自增數,代碼中的cur_weight。

 

 

        值得註意的是,加權輪詢本身還有不同的實現方式,雖說最終的比例都是2:1:2。但是在請求送達的先後順序上可以所有不同。比如「5-4,3,2-1」和上面的案例相比,最終比例是一樣的,但是效果不同。「5-4,3,2-1」更容易產生併發問題,導致服務端擁塞,且這個問題隨著權重數字越大越嚴重。例子:10:5:3的結果是「18-17-16-15-14-13-12-11-10-9,8-7-6-5-4,3-2-1」 

 

03  最少連接數

        這是一種根據實時的負載情況,進行動態負載均衡的方式。維護好活動中的連接數量,然後取最小的返回即可。大致的代碼如下。

 

var matchedServer = servers.orderBy(e => e.active_conns).first();

matchedServer.active_conns += 1;

return matchedServer;

//在連接關閉時還需對active_conns做減1的動作。

 

04  最快響應

        這也是一種動態負載均衡策略,它的本質是根據每個節點對過去一段時間內的響應情況來分配,響應越快分配的越多。具體的運作方式也有很多,上圖的這種可以理解為,將最近一段時間的請求耗時的平均值記錄下來,結合前面的「加權輪詢」來處理,所以等價於2:1:3的加權輪詢。

 

        題外話:一般來說,同機房下的延遲基本沒什麼差異,響應時間的差異主要在服務的處理能力上。如果在跨地域(例:浙江->上海,還是浙江->北京)的一些請求處理中運用,大多數情況會使用定時「ping」的方式來獲取延遲情況,因為是OSI的L3轉發,數據更乾凈,準確性更高。

 

05  Hash法

        hash法的負載均衡與之前的幾種不同在於,它的結果是由客戶端決定的。通過客戶端帶來的某個標識經過一個標準化的散列函數進行打散分攤

 

        上圖中的散列函數運用的是最簡單粗暴的「取餘法」。

        題外話:散列函數除了取餘之外,還有諸如「變基」、「摺疊」、「平方取中法」等等,此處不做展開,有興趣的小伙伴可自行查閱資料。

 

        另外,被求餘的參數其實可以是任意的,只要最終轉化成一個整數參與運算即可。最常用的應該是用來源ip地址作為參數,這樣可以確保相同的客戶端請求儘可能落在同一臺伺服器上。

 

 

三、常用「負載均衡」策略優缺點和適用場景

        我們知道,沒有完美的事物,負載均衡策略也是一樣。上面列舉的這些最常用的策略也有各自的優缺點和適用場景,我稍作了整理,如下。

 

 

        這些負載均衡演算法之所以常用也是因為簡單,想要更優的效果,必然就需要更高的複雜度。比如,可以將簡單的策略組合使用、或者通過更多維度的數據採樣來綜合評估、甚至是基於進行數據挖掘後的預測演算法來做。

 

 

四、用「健康探測」來保障高可用

        不管是什麼樣的策略,難免會遇到機器故障或者程式故障的情況。所以要確保負載均衡能更好的起到效果,還需要結合一些「健康探測」機制。定時的去探測服務端是不是還能連上,響應是不是超出預期的慢。如果節點屬於“不可用”的狀態的話,需要將這個節點臨時從待選取列表中移除,以提高可用性。一般常用的「健康探測」方式有3種。

 

01  HTTP探測

        使用Get/Post的方式請求服務端的某個固定的URL,判斷返回的內容是否符合預期。一般使用Http狀態碼、response中的內容來判斷。

 

02  TCP探測

        基於Tcp的三次握手機制來探測指定的IP + 埠。最佳實踐可以借鑒阿裡雲的SLB機制,如下圖。

▲圖片來源於阿裡雲,版權歸原作者所有


        值得註意的是,為了儘早釋放連接,在三次握手結束後立馬跟上RST來中斷TCP連接。

 

03  UDP探測

        可能有部分應用使用的UDP協議。在此協議下可以通過報文來進行探測指定的IP + 埠。最佳實踐同樣可以借鑒阿裡雲的SLB機制,如下圖。

▲圖片來源於阿裡雲,版權歸原作者所有

 

        結果的判定方式是:在服務端沒有返回任何信息的情況下,預設正常狀態。否則會返回一個ICMP的報錯信息。

 

 

五、結語

        用一句話來概括負載均衡的本質是:

        將請求或者說流量,以期望的規則分攤到多個操作單元上進行執行。

        通過它可以實現橫向擴展(scale out),將冗餘的作用發揮為「高可用」。另外,還可以物盡其用,提升資源使用率。

 

 

相關文章:

 

 

 

作者:Zachary(個人微信號:Zachary-ZF)

微信公眾號(首發):跨界架構師<-- 點擊後閱讀熱門文章,或右側掃碼關註 -->

定期發表原創內容:架構設計丨分散式系統丨產品丨運營丨一些深度思考


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 近幾年,微服務架構在後端技術社區大紅大紫,它被認為是IT軟體架構的未來技術方向.我們如何借鑒後端微服務的思想來構建一個現代化前端應用? 在這裡我提供一個可以在產品中真正可以落地的前端微服務解決方案. 微服務化後端前後端對比 後端微服務化的優勢: 1. 複雜度可控: 體積小、複雜度低,每個微服務可由一 ...
  • 在Bootstrap fileinput中移除預覽文件時可以通過配置initialPreviewConfig: [ { url:'deletefile',key:fileid } ] 來同步刪除伺服器上的文件和記錄。但新上傳的文件則需要其他方式來同步刪除伺服器記錄。 在配置中遇到的一些問題,記錄一下 ...
  • 數據流轉 先上一張圖看清 Westore 怎麼解決小程式數據難以管理和維護的問題: 非純組件的話,可以直接省去 triggerEvent 的過程,直接修改 store.data 並且 update,形成縮減版單向數據流。 "Github: https://github.com/dntzhang/we ...
  • 想在黑暗中看清周圍,不可避免地要用到夜視儀。那麼如果是想在黑暗中拍照,又沒有閃光燈,如何才能排到清晰的照片?在CVPR 2018上,英特爾實驗室的Vladlen Koltun和陳啟峰帶領的團隊提出了一種在黑暗中快速成像的系統,效果非常贊。 在暗光下的圖像易受到低信噪比和低亮度的影響。短曝光的照片會出 ...
  • 去年的時候寫過dubbo+zipkin調用鏈監控,最近看到zipkin2配合brave實現起來會比我之前的實現要簡單很多,因為brave將很多交互的內容都封裝起來了,不需要自己去寫具體的實現,比如如何去構建span,如何去上報數據。 收集器抽象 由於zipkin支持http以及kafka兩種方式上報 ...
  • 這兩年微服務越來越火,使用Consul的人也越來越多,這篇文章將結合Consul的官方文檔和自己的實際經驗,談一下Consul做服務發現的方式,文中儘量不依賴具體的框架和開發語言,從原理上進行說明,希望能夠講清楚幾個問題。 ...
  • 前期我們針對架構準備階段及需求分析這塊我們寫了2篇內容《HRMS(人力資源管理系統)-從單機應用到SaaS應用-架構分析(功能性、非功能性、關鍵約束)-上篇》《HRMS(人力資源管理系統)-從單機應用到SaaS應用-架構分析(功能性、非功能性、關鍵約束)-下篇》內容來展開說明。 本篇... ...
  • 零、 題記 在高併發場景下,需要通過緩存來減少資料庫的壓力,使得大量的訪問進來能夠命中緩存,只有少量的需要到資料庫層。由於緩存基於記憶體,可支持的併發量遠遠大於基於硬碟的資料庫。所以對於高併發設計,緩存的設計是必不可少的一環。一、為什麼要使用緩存 為什麼要使用緩存呢?源於人類的一個夢想,就是多快好省的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...