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