上一篇負載均衡的文章有一個點不少人有疑問,所以我覺得有必要單獨寫篇文章解釋一下,先看下上篇文章展示的架構圖:
這里一些朋友的疑問點是 Nginx 是否多此一舉,能否能直接從 LVS 打到站點層?即改成下面的架構
答案是不行,為什么?其實我在上文中有提到一些點已經(jīng)暗示了,只不過不那么明顯而已,我再單獨把這些點拎出來
LVS 是四層負載均衡器
Nginx 是七層負載均衡器,可以根據(jù) url 來轉發(fā)流量
首先我們需要明白為什么根據(jù) url 轉發(fā)請求這么重要,假設現(xiàn)在有「營銷」,「運營中心」這兩個集群,使用 Nginx 的話很簡單,根據(jù) url 來決定到底將請求轉發(fā)到哪個集群即可
由于 LVS 不能根據(jù) url 轉發(fā),那么請問 LVS 收到請求后該轉給誰
那么 LVS 為什么不能根據(jù) url 來轉發(fā)呢,因為它是四層負載均衡器,什么是四層和七層,這里就要簡單復習下 ISO 七層參考模型了
由此可知,七層對應著應用層,四層對應著傳輸層,如果從應用層發(fā)起一個請求會在「傳輸層」,「網(wǎng)絡層」,「數(shù)據(jù)鏈路層」分別加上各自層的包頭,比如現(xiàn)在 A 電腦要發(fā)一個「I‘m Deepon」數(shù)據(jù)給 B 電腦,則在各層的轉化流程如下圖所示
但最終在互聯(lián)網(wǎng)上要傳輸?shù)陌〝?shù)據(jù)鏈路層傳輸?shù)陌械?,統(tǒng)稱為包)是有大小限制的,如下圖所示
在互聯(lián)網(wǎng)上傳輸?shù)陌荒艹^ 14 + 20 + 20 + 1460 + 4 = 1518 byte,其中包含的應用層(即 payload)數(shù)據(jù)一次性不能超過 1460 個 byte,也就是說如果一個 HTTP 請求有 2000 byte,那么它必須分成兩個包發(fā)送才能在網(wǎng)絡上傳輸,再來看看 HTTP 的格式
如果一個 HTTP POST 請求很大,超過了 1460 byte(一個包 payload 的最大值),那么它必須分成兩個包才能傳輸,也就意味著一個包可能包含 URI,另一個包不包含 URI,既然包都不包含 URI,那么請問 LVS 如何根據(jù) URL 來轉發(fā)給相應的集群呢,所以理解了 TCP/IP 的工作機制相信你不難理解開頭的問題:LVS 是四層負載均衡器,無法根據(jù) URL 來轉發(fā)請求。
其實最關鍵的原因是四層以下其實只負責包的轉發(fā),只要拿出包頭查看一下 ip 地址就可知道該轉發(fā)哪里,很高效,如果你還要根據(jù) url 來匹配那么需要拿到應用層數(shù)據(jù)根據(jù)正則等做匹配,顯然會消耗更多的性能,所以專業(yè)的人做專業(yè)的事,應該由 LVS 來負責承載所有流量,Nginx 負責根據(jù) url 來轉發(fā)給對應的集群,因為它是七層負載均衡器,與上下游各建立了一個 TCP 鏈接
所以如果有多個分包,由于 Nginx 與 client 建立了 TCP 連接,可以在 Nginx 先拿到 client 發(fā)出的所有的分包再組裝成完整的報文, 然后根據(jù) url 選擇其中一臺 server 與之建立 TCP 連接后將數(shù)據(jù)分批完整地傳給上游 server
另外需要注意的是現(xiàn)在在大廠中如果只將 Nginx 作為轉發(fā)之用是不夠的,一般用的 OpenResty ,什么是 OpenResty 呢
“OpenResty 是一個基于 Nginx 與 Lua 的高性能 Web 平臺,其內(nèi)部集成了大量精良的 Lua 庫、第三方模塊以及大多數(shù)的依賴項。用于方便地搭建能夠處理超高并發(fā)、擴展性極高的動態(tài) Web 應用、Web 服務和動態(tài)網(wǎng)關。
OpenResty 的目標是讓你的 Web 服務直接跑在 Nginx 服務內(nèi)部,充分利用 Nginx 的非阻塞 I/O 模型,不僅僅對 HTTP 客戶端請求,甚至于對遠程后端諸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都進行一致的高性能響應?!?/p>
注意上面一句「提供了與 MySQL ,Redis 等的交互能力」這一點非常關鍵,我們之前不是說 Nginx 可以根據(jù) url 來決定打向哪個集群嗎,假設現(xiàn)在有一個這樣的場景:所有包含 operation 的請求都轉發(fā)到運營中心的集群,則需要寫死類似如下的配置
upstream backend {
server 192.168.1.10:8080
server 192.168.1.11:8080
}
server {
location /operation {
proxy_pass http://backed
}
}
在我們集團中類似這樣的規(guī)則非常多,難道要像上面這樣把所有的規(guī)則都一個個寫死在 Nginx 的配置文件里嗎?顯然不可行,更合理的方式是把這些規(guī)則(哪個 url 對應哪些集群)保存在 MySQL 中,然后 Nginx 在啟動的時候?qū)⑦@些規(guī)則從 MySQL 中取出并保存在 Redis 及本地緩存中,然后 Nginx 要根據(jù) url 匹配的時候從本地緩存(如果沒有從 redis 拿,redis 過期從 MySQL 拿)里拿這些規(guī)則再根據(jù)匹配項轉發(fā)到相應的集群,Nginx 沒有這樣的能力,而 OpenResty 由于集成了 Lua,引入了與 MySQL, Redis 等交互的模塊,所以用它是可行的,所以最終架構如下(將 Nginx 換成 OpenResty)
責任編輯:haq
-
負載均衡
+關注
關注
0文章
98瀏覽量
12337 -
LVS
+關注
關注
1文章
35瀏覽量
9897
原文標題:再談負載均衡
文章出處:【微信號:gh_3980db2283cd,微信公眾號:開關電源芯片】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論