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

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

當前大多數的網際網路系統都使用了伺服器叢集技術,叢集是將相同服務部署在多臺伺服器上構成一個叢集整體對外提供服務,這些叢集可以是 Web 應用伺服器叢集,也可以是資料庫伺服器叢集,還可以是分散式快取伺服器叢集等等。

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

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

LVS、Nginx、HAProxy 是目前使用最廣泛的三種軟體負載均衡軟體。

一般對負載均衡的使用是隨著網站規模的提升根據不同的階段來使用不同的技術。具體的應用需求還得具體分析,如果是中小型的 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:

鐘武

https://zhongwuzw.github.io

王晨純

http://www.importnew.com/11229.html

周旭龍

http://edisonchou.cnblogs.com

    已同步到看一看
    贊(0)

    分享創造快樂