最近有小夥伴在後臺留言,讓我寫一篇負載均衡的文章,說網上文章其實已經不少了,每次都以爲某某文章講的不錯,但是一旦過段時間,啥都不記得了。那今天咱們就用生活中的故事來聊聊負載均衡。文章中部分可能有點囉嗦,可是爲了更好能讓你們理解,我也是拼了nginx
,真真切切的想讓你們掌握知識。web
負載均衡,英文名稱爲Load Balance,其含義就是指將負載(工做任務)進行平衡、分攤到多個操做單元上進行運行,例如FTP服務器、Web服務器、企業核心應用服務器和其它主要任務服務器等,從而協同完成工做任務。算法
負載均衡一般有兩種目的:均攤壓力和提供冗餘(也能夠理解爲備份)。sql
生活案列數據庫
上面還看不懂的話,咱們繼續用生活案列來講:apache
高速路出口處,若是隻有一個出口時,忽然有一天出現大量車輛(假設你們都沒有辦理ETC)這個高速出口下高速, 好比有幾百兩這會都要下高速,可是下高速要交過路費,每輛車至少也要耽擱幾分鐘,幾百輛!!!意味着後面的可能要等幾個小時,若是有多個出口呢?那就不必等那麼久了。後端
若是在增長一個出口,這時候就是兩個出口能夠均攤車輛下高速,還得分收費員快慢,車輛3看到車1那邊要快點,而後就跟上車1。瀏覽器
若是再增長n個就能夠想象效果了。可是太多了,貌似也會形成資源浪費,不少出口一天都沒有幾輛車出入,若是搞得太多豈不浪費,因此咱們通常看到大多數都是兩個,能夠理解備用急用。緩存
「咱們就把司機理解爲負載均衡器,能夠根據前方路況進行判別走哪一個出口。判別的方法就能夠理解爲負載均衡算法。」安全
用咱們技術領域的術語叫作冗餘。收費員的速度我就能夠理解爲咱們系統某個服務的性能。
技術領域
下面用一張圖來描述咱們技術領域的負載均衡:
結合生活中的場景和技術領域的場景一塊兒理解更酸爽。
注意:集羣指的是咱們同一個App應用服務的部署多個節點,集羣的主要目的就是爲了分擔壓力的。負載均衡器(系統)就能夠理解爲指揮員。來一個請求,指揮員把這個請求根據必定方法交給集羣中的某個服務。指揮員就能夠按照各類方式進行分配請求到集羣中的某個服務。隨機給、排隊給、誰反應快給誰等方法,也就是造成了負載均衡算法。
以上比喻僅僅是我的理解。
DNS
(Domain Name System 域名系統 )它做爲將域名和IP地址相互映射的一個分佈式數據庫,可以令人更方便地訪問互聯網。DNS使用TCP和UDP端口53。當前,對於每一級域名長度的限制是63個字符,域名總長度則不能超過253個字符。DNS是最簡單也是最多見的負載均衡方式,通常用來實現「地理級別」的負載均衡,好比說:北方人訪問北京的機房,南方人訪問廣州的機房,西方人訪問成都的機房。DNS負載均衡的本質是DNS解析同一個域名能夠返回不一樣的IP地址。好比說:https://www.sina.com.cn/在北方的用戶使用時會解析成10.210.1.12(北京機房)返回,南方的用戶使用時會解析成14.213.164.27返回(廣州機房)。
DNS簡單示意圖
優勢
配置簡單,無成本費用
將負載均衡的工做交給了DNS服務器,省去了管理的麻煩。
缺點
記錄的添加與修改是須要必定時間纔可以生效的(由於DNS緩存了A記錄)。一旦有一臺服務器壞了須要下線,即便修改了A記錄,要使其生效也須要較長的時間,這段時間,DNS仍然會將域名解析到已下線的服務器上,最終致使用戶訪問失敗。
不能按需分配負載,DNS並不知道各服務器的真實負載狀況,因此負載效果不是很好
實際的狀況:在實際的項目部署,咱們通常會將部分服務器使用DNS解析,利用域名解析做爲第一級負載均衡.再在服務器中使用nginx負載均衡做爲第二級負載均衡。
硬件負載均衡
硬件負載均衡是經過單獨的設備來實現負載均衡的功能,這類設備和路由器交換機有那麼一些相似,更或者能夠理解爲一個用於負載均衡的基礎網絡設備。目前業界主要有兩款硬件負載均衡:F5和A10。這類設備性能好,功能強大,可是價格能夠用昂貴來形容,通常只有銀行,國企等大型有錢的企業開會考慮使用此類設備,本人也只是在銀行裏見識過F5。至於A10沒接觸過就不撤了。
優勢
功能強大:全面支持各層級的負載均衡,支持各類負載均衡算法,支持全局負載均衡。
性能好:通常軟件負載均衡能支撐10w+併發已經很不錯了,可是硬件的負載均衡卻能夠支持100w+以上的併發。
高穩定性:由於是商業品,因此通過了良好嚴格的測試,通過大規模的使用,因此穩定很是高。
安全性高:硬件負載均衡設備除了能處理負載均衡之外,還具備防火牆、防DDOS***等效果。
缺點
價格昂貴:我記得以前銀行購買F5花了上百萬,聽說還有更貴的,因此價格可想而知。
擴展性很差:硬件設備能夠根據業務進行配置,但沒法進行擴展和定製化。
軟件負載均衡
軟件負載均衡是經過負載均衡軟件來實現負載均衡功能的。常見的負載均衡軟件有LVS和Nginx。其中LVS是Linux內核的四層負載均衡,四層和七層的區別在於他們協議和靈活性的不一樣。Nginx是7層負載均衡,支持HTTP,E-mail協議,而LVS是四層負載均衡,因此和協議無關,基本上全部應用均可以作到,好比說:聊天、數據庫等。
如下是Nginx的負載均衡簡單示意圖:
優勢
nginx由C編寫,一樣的web服務器,佔用的資源和內存低性能高。
當啓動nginx服務器,會生成一個master進程,master進程會fork出多個worker進程,由worker線程處理客戶端的請求。
nginx支持高併發,每一個worker子進程是獨立平等的,當有客戶端請求時,worker進程公平競爭,搶到的worker進程會把請求提交給後端服務器,當後端服務器沒有及時響應時,此worker進程會繼續接收下一個request,當上一個請求有響應後會觸發事件,此worker進程繼續以前的執行,知道響應結束。一個request不會被兩個worker進程執行。
nginx支持反向代理(用戶有感知的訪問叫正向代理如使用***訪問youtube,用戶無感知訪問叫反向代理如負載均衡),支持7層負載均衡(拓展負載均衡的好處)。
nginx是異步非阻塞型處理請求(第三點印證),採用的epollandqueue模式,apache是阻塞型處理請求。
nginx處理靜態文件速度快(緣由:
nginx高度模塊化,配置簡單。
nginx是單進程多線程)。
缺點
對比apache不穩定,因爲是單進程多線程,進程死掉會影響不少用戶。
「流量分發」負載均衡能對多臺主機流量進行分發,提升用戶系統的業務處理能力,提高服務可用性
「會話保持」在會話週期內,會話保持可以使來自同一IP或網段的請求被分發到同一臺後端服務器上。
「健康檢查」支持自定義健康檢查方式和頻率,可定時檢查後端主機運行狀態,提供故障轉移,實現高可用;
「負載均衡」解決併發壓力,提升應用處理性能(增長吞吐量,增強網絡處理能力);
提升擴展性經過添加或減小服務器數量,提供網站伸縮性(擴展性);
提升安全性安全防禦,在負載均衡器上作一些過濾,黑白名單、防盜鏈等處理;
輪訓
負載均衡系統接收到請求後,按照必定順序將請求分發給服務器上。輪訓是一種簡單的負載均衡算法策略,不會去關注服務器狀態。
優勢:若是服務器都是正常的,那麼輪訓是最理想的,由於它會使得每一個服務都獲得相等量的請求,能夠用"雨露均沾"來形容。
缺點:上面的有點是理想狀態的,可是現實每每不是那樣的,現實仍是很骨感滴,線上系統每每出現各類各樣的問題,好比:當有一臺服務器掛了,輪訓算法不會管服務器狀態,就是會致使大量的請求到一臺已經掛掉的服務器上,從而致使系統不可用,進而形成用戶流失。另一種常見的問題就是有的服務器響應快,有的響應慢(好比32核的服務器和16核的服務器),輪訓算法也不關注相應快慢,因此會致使不少服務請求響應時間慢,簡單的致使用戶體驗很差,因爲響應時間慢甚至可能拖垮其餘系統。
加權輪訓
負載均衡系統根據服務器權重進行請求任務分派到對應的服務器上,這裏的權重通常是根據系統硬件配置進行靜態配置的,採用動態的方式計算會更加適合業務,可是複雜度相比簡單的輪訓就高不少。
加權輪訓是輪訓的一種特殊方式,主要目的是解決服務器處理能力的差別問題,好比:集羣中有的服務器是32核,有的老系統倒是16核,那麼理論上咱們能夠對其進行權重配置值,即就是32核服務器的處理能力是16核的兩倍,負載均衡算法權重比例調整爲2:1,讓更多的請求分發給32核的服務器。
加權輪訓解決了輪訓算法中誤服根據服務器的配置的差別任務進行更好的分配的問題,其實仍是會存在沒法根據服務器的狀態差別性進行請求任務分配的問題。
負載最低優先
負載系統將請求分配給當前負載最低的服務器,這裏的負載根據不一樣請求類型和業務處理場景,能夠用不一樣的指標來衡量。好比如下幾個場景,
LVS這種4層網絡負載均衡設備,能夠以鏈接數來判斷服務器的狀態,服務器鏈接數量越大,代表服務器壓力就越大。
Nginx這種7層網絡負載均衡系統,能夠以HTTP請求數量判斷服務器的狀態(Nginx內置的負載均衡算法不支持這種方式,須要自行進行擴展)。
若是咱們是本身研發負載均衡系統,能夠根據業務特色來選擇衡量系統壓力的指標。若是CPU是密集型,能夠以CPU負載來衡量系統的壓力;若是是IO密集型,則能夠以IO負載來衡量系統壓力。
負載最低優先算法解決了輪訓算法中沒法感知服務器狀態的問題,可是由此帶來的代價是複雜度增長不少,好比:
最少連接數優先的算法要求負載系通通計每一個服務器當前簡歷的連接,其應用場景僅限於負載均衡接收的任何請求都會轉發給服務器進行處理,不然若是負載均衡系統和服務之間是固定的鏈接池方式,就不適合採起這種算法。LVS能夠採起這種算法進行負載均衡,而一個經過鏈接池的方式連接數據庫Mysql集羣的負載均衡系統就不適合採起這種算法進行負載均衡了。
CPU負載均衡最低優先的算法要求負載均衡系統以某種方式收集每一個服務器的CPU的具體負載狀況,同時要肯定是以一分鐘的負載標準,仍是以10分鐘、15分鐘的負載標準,不存在1分鐘確定比15分鐘的好或差。不一樣業務最優的時間間隔也是不同的,時間間隔過短容易形成頻繁波動,時間太長可能形成峯值來臨時響應緩慢。
負載最低優先的算法基板上可以很完美解決了輪訓算法的缺點,也由於採用負載最低優先算法後,負載均衡系統須要感知服務器當前運行狀態,此時,一樣形成代價上升不少。對於開發者來講也許輪訓算法只要簡短的代碼就能夠實現,然而負載最低優先算法須要大量的代碼來實現。
負載最低優先看起來是解決了輪訓中的缺點,而後因爲其複雜度的提高,致使真正使用中比例還不如輪訓或者輪訓加權算法。
性能最優
負載最低優先算法是站在服務器的角度來進行請求分配的,而性能最優算法是站在客戶端的角度進行分配的,優先將請求分配給處理速度快的服務器,經過這種方式達到了最快響應給客戶端。
性能優先其實也負載最低優先有點相似,都是須要感知服務器的狀態,與之不一樣的是性能最優是經過響應時間這個標準,在外部進行感應服務器狀態而已,一樣的實現複雜度也很高,主要體如今如下方面:
負載均衡系統須要收集每次請求的響應時間,若是在大量請求處理的場景下,這種收集再加上響應時間的統計自己也會消耗系統的性能。
爲了減小這種統計上的消耗,能夠採起採樣的方式進行統計,即就是不用很徹底的去統計全部服務器的全部請求時間,而是抽樣統計部分任務的響應時間來估算總體請求所花的響應時間。採樣統計雖然能減輕性能的消耗,但使得實現的複雜度增長了不少,由於要肯定合適的採樣率,採樣率過低會致使數據的正確性,採樣率高一樣會形成性能的消耗,要找到一個合適的採樣率的複雜度也是可想而知的。
不管所有統計,仍是採樣統計,都須要選擇合適的週期,是30秒性能最優仍是1分鐘最優?目前是沒有標準的週期,都是須要具體業務場景進行決策,是否是感受到了其複雜性,尤爲是線上系統須要不斷的調試,而後找出相對合適的標準。
Hash類
負載均衡系統根據請求中某些關鍵字進行hash運算,獲得的相同值得分發到同一臺服務器上去,這樣作的目的主要是爲了知足特定的業務需求,好比:
源地址Hash:未來源於同一個IP地址的請求分配給同一個服務器進行處理,適合於存在事務、會話的業務。例如:當咱們經過瀏覽器登陸網上銀行時,會生成一個會話信息,這個會話是臨時的,關閉瀏覽器後就會失效。網上銀行後臺無須持久會話信息,只須要在某臺服務器臨時保留這個會話就能夠了,但須要保證用戶在會話存在期間,每次請求都能訪問在同一個服務器,這種業務場景就是經過源地址hash來實現的。
ID hash :將某個ID表示的業務分配到同一臺服務器上進行處理,好比:userId session id。上述的網上銀行登陸的例子,用session id hash能夠實現同一個會話期間,用戶每次都是訪問同一臺服務器上的目的。
Dubbo中使用了哪些負載均衡算法?
Random LoadBalance(隨機算法,默認)
RoundRobin LoadBalance(權重輪訓算法)
LeastAction LoadBalance(最少活躍調用數算法)
ConsistentHash LoadBalance(一致性Hash法)
類圖
nginx中使用了哪些負載均衡算法?
「round robin(默認)」:輪詢方式,依次將請求分配到各個後臺服務器中,默認的負載均衡方式。適用於後臺機器性能一致的狀況。掛掉的機器能夠自動從服務列表中剔除。
「weight」:根據權重來分發請求到不一樣的機器中,指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況。 例如:
upstream bakend {
server 192.168.0.14 weight=10;
server 192.168.0.15 weight=10;
}
「IP_hash」:根據請求者ip的hash值將請求發送到後臺服務器中,能夠保證來自同一ip的請求被打到固定的機器上,能夠解決session問題。例如:
upstream bakend {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
「url_hash(第三方)」:根據請求的url的hash值將請求分到不一樣的機器中,當後臺服務器爲緩存的時候效率高。
例如:在upstream中加入hash語句,server語句中不能寫入weight等其餘的參數,hash_method是使用的hash算法 。
「fair(第三方)」:根據後臺響應時間來分發請求,響應時間短的分發的請求多。例如:
upstream backend {
server server1;
server server2;
fair;
}
咱們用生活中的故事來說述了負載均衡,講述了什麼是負載均衡,負載均衡的做用,負載均衡的種類,負載均衡算法種類,以及咱們在Dubbo和nginx中負載均衡算法的應用。
但願老鐵能get到點!若有疑問或什麼建議的加我微信tj20120622咱們慢慢聊。直到讓你們理解掌握爲止。
「只要咱們的方向對了,就不怕路遠!」
碼字不易,點個讚唄