一文詳解 LVS、Nginx 及 HAProxy 工做原理( 附大圖 )

當前大多數的互聯網系統都使用了服務器集羣技術,集羣是將相同服務部署在多臺服務器上構成一個集羣總體對外提供服務,這些集羣能夠是 Web 應用服務器集羣,也能夠是數據庫服務器集羣,還能夠是分佈式緩存服務器集羣等等。html

 

 

在實際應用中,在 Web 服務器集羣以前總會有一臺負載均衡服務器,負載均衡設備的任務就是做爲 Web 服務器流量的入口,挑選最合適的一臺 Web 服務器,將客戶端的請求轉發給它處理,實現客戶端到真實服務端的透明轉發。前端

最近幾年很火的「雲計算」以及分佈式架構,本質上也是將後端服務器做爲計算資源、存儲資源,由某臺管理服務器封裝成一個服務對外提供,客戶端不須要關心真正提供服務的是哪臺機器,在它看來,就好像它面對的是一臺擁有近乎無限能力的服務器,而本質上,真正提供服務的,是後端的集羣。git

LVS、Nginx、HAProxy 是目前使用最普遍的三種軟件負載均衡軟件。github

通常對負載均衡的使用是隨着網站規模的提高根據不一樣的階段來使用不一樣的技術。具體的應用需求還得具體分析,若是是中小型的 Web 應用,好比日 PV 小於1000萬,用 Nginx 就徹底能夠了;若是機器很多,能夠用 DNS 輪詢,LVS 所耗費的機器仍是比較多的;大型網站或重要的服務,且服務器比較多時,能夠考慮用 LVS。正則表達式

目前關於網站架構通常比較合理流行的架構方案:Web 前端採用 Nginx/HAProxy+Keepalived 做負載均衡器;後端採用 MySQ L數據庫一主多從和讀寫分離,採用 LVS+Keepalived 的架構。數據庫

LVS

LVS 是 Linux Virtual Server 的簡稱,也就是 Linux 虛擬服務器。如今 LVS 已是 Linux 標準內核的一部分,從 Linux2.4 內核之後,已經徹底內置了 LVS 的各個功能模塊,無需給內核打任何補丁,能夠直接使用 LVS 提供的各類功能。後端

LVS 自從1998年開始,發展到如今已是一個比較成熟的技術項目了。瀏覽器

LVS 的體系結構

 

 

LVS 架設的服務器集羣系統有三個部分組成:緩存

(1) 最前端的負載均衡層,用 Load Balancer 表示服務器

(2) 中間的服務器集羣層,用 Server Array 表示

(3) 最底端的數據共享存儲層,用 Shared Storage 表示

 

LVS 負載均衡機制

LVS 不像 HAProxy 等七層軟負載面向的是 HTTP 包,因此七層負載能夠作的 URL 解析等工做,LVS 沒法完成。

LVS 是四層負載均衡,也就是說創建在 OSI 模型的第四層——傳輸層之上,傳輸層上有咱們熟悉的 TCP/UDP,LVS 支持 TCP/UDP 的負載均衡。由於 LVS 是四層負載均衡,所以它相對於其它高層負載均衡的解決辦法,好比 DNS 域名輪流解析、應用層負載的調度、客戶端的調度等,它的效率是很是高的。

所謂四層負載均衡 ,也就是主要經過報文中的目標地址和端口。七層負載均衡 ,也稱爲「內容交換」,也就是主要經過報文中的真正有意義的應用層內容。

 

 

LVS 的轉發主要經過修改 IP 地址(NAT 模式,分爲源地址修改 SNAT 和目標地址修改 DNAT)、修改目標 MAC(DR 模式)來實現。

NAT 模式:網絡地址轉換

NAT(Network Address Translation)是一種外網和內網地址映射的技術。

NAT 模式下,網絡數據報的進出都要通過 LVS 的處理。LVS 須要做爲 RS(真實服務器)的網關。

當包到達 LVS 時,LVS 作目標地址轉換(DNAT),將目標 IP 改成 RS 的 IP。RS 接收到包之後,彷彿是客戶端直接發給它的同樣。RS 處理完,返回響應時,源 IP 是 RS IP,目標 IP 是客戶端的 IP。這時 RS 的包經過網關(LVS)中轉,LVS 會作源地址轉換(SNAT),將包的源地址改成 VIP,這樣,這個包對客戶端看起來就彷彿是 LVS 直接返回給它的。

 

 

DR 模式:直接路由

DR 模式下須要 LVS 和 RS 集羣綁定同一個 VIP(RS 經過將 VIP 綁定在 loopback 實現),但與 NAT 的不一樣點在於:請求由 LVS 接受,由真實提供服務的服務器(RealServer,RS)直接返回給用戶,返回的時候不通過 LVS。

詳細來看,一個請求過來時,LVS 只須要將網絡幀的 MAC 地址修改成某一臺 RS 的 MAC,該包就會被轉發到相應的 RS 處理,注意此時的源 IP 和目標 IP 都沒變,LVS 只是作了一下移花接木。RS 收到 LVS 轉發來的包時,鏈路層發現 MAC 是本身的,到上面的網絡層,發現 IP 也是本身的,因而這個包被合法地接受,RS 感知不到前面有 LVS 的存在。而當 RS 返回響應時,只要直接向源 IP(即用戶的 IP)返回便可,再也不通過 LVS。

 

 

DR 負載均衡模式數據分發過程當中不修改 IP 地址,只修改 mac 地址,因爲實際處理請求的真實物理 IP 地址和數據請求目的 IP 地址一致,因此不須要經過負載均衡服務器進行地址轉換,可將響應數據包直接返回給用戶瀏覽器,避免負載均衡服務器網卡帶寬成爲瓶頸。所以,DR 模式具備較好的性能,也是目前大型網站使用最普遍的一種負載均衡手段。

LVS 的優勢

  • 抗負載能力強、是工做在傳輸層上僅做分發之用,沒有流量的產生,這個特色也決定了它在負載均衡軟件裏的性能最強的,對內存和 cpu 資源消耗比較低。
  • 配置性比較低,這是一個缺點也是一個優勢,由於沒有可太多配置的東西,因此並不須要太多接觸,大大減小了人爲出錯的概率。
  • 工做穩定,由於其自己抗負載能力很強,自身有完整的雙機熱備方案,如 LVS + Keepalived。
  • 無流量,LVS 只分發請求,而流量並不從它自己出去,這點保證了均衡器 IO 的性能不會受到大流量的影響。
  • 應用範圍比較廣,由於 LVS 工做在傳輸層,因此它幾乎能夠對全部應用作負載均衡,包括 http、數據庫、在線聊天室等等。

LVS 的缺點

  • 軟件自己不支持正則表達式處理,不能作動靜分離;而如今許多網站在這方面都有較強的需求,這個是 Nginx、HAProxy + Keepalived 的優點所在。
  • 若是是網站應用比較龐大的話,LVS/DR + Keepalived 實施起來就比較複雜了,相對而言,Nginx / HAProxy + Keepalived 就簡單多了。

Nginx

Nginx 是一個強大的 Web 服務器軟件,用於處理高併發的 HTTP 請求和做爲反向代理服務器作負載均衡。具備高性能、輕量級、內存消耗少,強大的負載均衡能力等優點。

 

 

Nignx 的架構設計

相對於傳統基於進程或線程的模型(Apache就採用這種模型)在處理併發鏈接時會爲每個鏈接創建一個單獨的進程或線程,且在網絡或者輸入/輸出操做時阻塞。這將致使內存和 CPU 的大量消耗,由於新起一個單獨的進程或線程須要準備新的運行時環境,包括堆和棧內存的分配,以及新的執行上下文,固然,這些也會致使多餘的 CPU 開銷。最終,會因爲過多的上下文切換而致使服務器性能變差。

反過來,Nginx 的架構設計是採用模塊化的、基於事件驅動、異步、單線程且非阻塞。

Nginx 大量使用多路複用和事件通知,Nginx 啓動之後,會在系統中以 daemon 的方式在後臺運行,其中包括一個 master 進程,n(n>=1) 個 worker 進程。全部的進程都是單線程(即只有一個主線程)的,且進程間通訊主要使用共享內存的方式。

其中,master 進程用於接收來自外界的信號,並給 worker 進程發送信號,同時監控 worker 進程的工做狀態。worker 進程則是外部請求真正的處理者,每一個 worker 請求相互獨立且平等的競爭來自客戶端的請求。請求只能在一個 worker 進程中被處理,且一個 worker 進程只有一個主線程,因此同時只能處理一個請求。(原理同 Netty 很像)

 

 

Nginx 負載均衡

Nginx 負載均衡主要是對七層網絡通訊模型中的第七層應用層上的 http、https 進行支持。

Nginx 是以反向代理的方式進行負載均衡的。反向代理(Reverse Proxy)方式是指以代理服務器來接受 Internet 上的鏈接請求,而後將請求轉發給內部網絡上的服務器,並將從服務器上獲得的結果返回給 Internet 上請求鏈接的客戶端,此時代理服務器對外就表現爲一個服務器。

Nginx 實現負載均衡的分配策略有不少,Nginx 的 upstream 目前支持如下幾種方式:

  • 輪詢(默認):每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器 down 掉,能自動剔除。
  • weight:指定輪詢概率,weight 和訪問比率成正比,用於後端服務器性能不均的狀況。
  • ip_hash:每一個請求按訪問 ip 的 hash 結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決 session 的問題。
  • fair(第三方):按後端服務器的響應時間來分配請求,響應時間短的優先分配。
  • url_hash(第三方):按訪問 url 的 hash 結果來分配請求,使每一個 url 定向到同一個後端服務器,後端服務器爲緩存時比較有效。

Nginx 的優勢

  • 跨平臺:Nginx 能夠在大多數 Unix like OS編譯運行,並且也有 Windows 的移植版本
  • 配置異常簡單:很是容易上手。配置風格跟程序開發同樣,神通常的配置
  • 非阻塞、高併發鏈接:官方測試可以支撐5萬併發鏈接,在實際生產環境中跑到2~3萬併發鏈接數
  • 事件驅動:通訊機制採用 epoll 模型,支持更大的併發鏈接
  • Master/Worker 結構:一個 master 進程,生成一個或多個 worker 進程
  • 內存消耗小:處理大併發的請求內存消耗很是小。在3萬併發鏈接下,開啓的10個 Nginx 進程才消耗150M 內存(15M*10=150M)
  • 內置的健康檢查功能:若是 Nginx 代理的後端的某臺 Web 服務器宕機了,不會影響前端訪問
  • 節省帶寬:支持 GZIP 壓縮,能夠添加瀏覽器本地緩存的 Header 頭
  • 穩定性高:用於反向代理,宕機的機率微乎其微

Nginx 的缺點

  • Nginx 僅能支 持http、https 和 Email 協議,這樣就在適用範圍上面小些,這個是它的缺點
  • 對後端服務器的健康檢查,只支持經過端口來檢測,不支持經過 ur l來檢測。不支持 Session 的直接保持,但能經過 ip_hash 來解決

HAProxy

HAProxy 支持兩種代理模式 TCP(四層)和HTTP(七層),也是支持虛擬主機的。

HAProxy 的優勢可以補充 Nginx 的一些缺點,好比支持 Session 的保持,Cookie 的引導;同時支持經過獲取指定的 url 來檢測後端服務器的狀態。

HAProxy 跟 LVS 相似,自己就只是一款負載均衡軟件;單純從效率上來說 HAProxy 會比 Nginx 有更出色的負載均衡速度,在併發處理上也是優於 Nginx 的。

HAProxy 支持 TCP 協議的負載均衡轉發,能夠對 MySQL 讀進行負載均衡,對後端的 MySQL 節點進行檢測和負載均衡,你們能夠用 LVS+Keepalived 對 MySQL 主從作負載均衡。

HAProxy 負載均衡策略很是多:Round-robin(輪循)、Weight-round-robin(帶權輪循)、source(原地址保持)、RI(請求URL)、rdp-cookie(根據cookie)。

Reference:

鍾武

王晨純

周旭龍

原文:
相關文章
相關標籤/搜索