Nginx,為什么依舊這么“香”?
Nginx 很好用,幾乎每個(gè)公司都在用,它的功能主要有反向代理、 負(fù)載均衡、 動(dòng)靜分離等,其中最主要的就是反向代理。
圖片來(lái)自 Pexels
它的主要架構(gòu)圖如下:
客戶端是無(wú)法直接訪問(wèn)后端的 Server 的,因?yàn)?Server 資源高高在上,Client 并沒(méi)有權(quán)限。
這個(gè)時(shí)候,就需要有一個(gè) Proxy,進(jìn)行代理,將客戶端的請(qǐng)求進(jìn)行轉(zhuǎn)發(fā),然后把結(jié)果返回給 Client。
為什么不能直接讓 Client 訪問(wèn) Server 呢?這就涉及到資源隔離問(wèn)題。Server 的一些真實(shí)意圖,是不想要 Client 知曉的,比如一些受安全保護(hù)的敏感資源。
也就是說(shuō),通過(guò) Proxy,Server 想讓 Client 看到啥,Client 也只能看到啥。對(duì) Client 來(lái)說(shuō),功能總是閹割的!甚至是篡改的!
我們將圖中的元素替換一下,奇妙的事情發(fā)生了。
我們把 Client 換成可憐的普通碼農(nóng),把 Server 換成牛 X 的領(lǐng)導(dǎo),可以看到 6 條綠色的箭頭,帶著呼嘯的山風(fēng),無(wú)情的指向了 Proxy。
Proxy 成為了關(guān)鍵的資源。這個(gè) Proxy 要求可不簡(jiǎn)單,需要五弊三缺,上承天命,下召九幽。這么牛 X 的存在,當(dāng)之無(wú)愧稱之為 Nginx 工程師。
Nginx 工程師不需要有自己的想法,但他必須記住領(lǐng)導(dǎo)的每一句話,領(lǐng)會(huì)領(lǐng)導(dǎo)的真實(shí)意圖。
傳導(dǎo)領(lǐng)導(dǎo)想法的時(shí)候,也知道輕重,知道過(guò)濾,能夠快狠準(zhǔn)的將領(lǐng)導(dǎo)的想法廣播出去。不服不行,這還真不是一般人能做的。
哪些人能夠成為 Nginx 工程師呢?在奴隸社會(huì),無(wú)論一個(gè)奴隸(Slave)工作多么的賣(mài)力,能力多么的出眾,都沒(méi)有出頭之日。
反而是那些拿著鞭子的監(jiān)工們,更容易獲得主人們的贊賞,喝酒吃肉的時(shí)候都能夠想到他們。
更加奇妙的是,如果把監(jiān)工們和奴隸們的工作調(diào)換一下。奴隸有可能會(huì)勝任監(jiān)工的工作,而監(jiān)工絕無(wú)可能勝任奴隸的工作。
這是為什么呢?總結(jié)下來(lái)可以有這么幾點(diǎn):
- 監(jiān)工知道更多的內(nèi)幕資源,更容易投主人所好。
- 監(jiān)工的工作屬性是管理,可操作空間大。
- 監(jiān)工離權(quán)利中心更近,耳邊風(fēng)吹的頻率要高一些。
你可能會(huì)說(shuō),這是社會(huì)性質(zhì)使然,現(xiàn)在的社會(huì)肯定沒(méi)這問(wèn)題。你答對(duì)了一半,問(wèn)題就出在這里。
由于每個(gè)公司的進(jìn)化程度不一,程序員在不同的公司,獲得的感受和受到的待遇,也是非常大的。你甚至?xí)a(chǎn)生圖中爸爸的心態(tài)。
監(jiān)工一般都不是一線,離生產(chǎn)是比較遠(yuǎn)的,對(duì)于 Client 的想法,只能領(lǐng)會(huì)一點(diǎn)點(diǎn)。這一點(diǎn)點(diǎn)傳導(dǎo)到 Server 那里的,正確性更難以保證。
而且,監(jiān)工由于領(lǐng)會(huì)領(lǐng)導(dǎo)意圖和匯總 Excel,耗費(fèi)了大量的精力,花在真正有意義的事上的時(shí)間,就少的可憐。那怎么辦呢?只好拿 Client 的成果當(dāng)作自己的成果。
所以,悶頭寫(xiě)代碼的程序員,可能會(huì)發(fā)現(xiàn)自己做了很多工作,經(jīng)過(guò) Proxy 的一加工一轉(zhuǎn)達(dá),到了領(lǐng)導(dǎo)那里就是個(gè)屁。
Proxy 做的沒(méi)錯(cuò),996 的 Client 深夜也需要調(diào)代碼,Proxy 只需要在一旁刷 TikTok 就可以了。工作強(qiáng)度不一樣,工時(shí)自然就沒(méi)有衡量對(duì)比的價(jià)值。
我們可以再看 Proxy 的 3 種傳導(dǎo)場(chǎng)景。
場(chǎng)景 1:
- server:要加強(qiáng)員工文化建設(shè)。
- proxy:周六、周末去團(tuán)建,AA
- client: WCNM
場(chǎng)景 2:
- server:公司要勤儉節(jié)約。
- proxy:從明天開(kāi)始不提供廁紙和開(kāi)水
- client: WCNM
場(chǎng)景 3:
- server:王xx同學(xué)拼搏奮斗,是公司的楷模。
- proxy:開(kāi)啟狼性文化,明起996
- client: WCNM
可以看到,這一層的 Proxy 素質(zhì)尤其重要。如果你不巧碰見(jiàn)了一個(gè)水貨 Proxy,你的悲慘程度可想而知。
但如果你遇到一個(gè) Nice 的 Proxy,那就珍惜他,因?yàn)樗械膲毫Γ夹枰伤麄鲗?dǎo)。
那一般的 Nginx 工程師是怎么做的呢?為了讓驢拉磨,人們想出四招:蒙眼睛、捂嘴巴、堵耳朵、抽鞭子。
同樣,要想 Proxy 順利推行,Proxy 就可以不讓你看到某些事情;你想要發(fā)表意見(jiàn)的時(shí)候,使用暴力手段堵住你的嘴;當(dāng)你想要聆聽(tīng)領(lǐng)導(dǎo)真實(shí)意圖,堵住你的耳朵;當(dāng)你有所懈怠的時(shí)候,使用鞭子督促你完成工作。
很多公司由于人員眾多,結(jié)構(gòu)復(fù)雜,就存在著多層 Proxy 的拓?fù)?。這種公司非常的精彩,一個(gè) Proxy,可以作為另一個(gè) Proxy 的 Client,很多時(shí)候,竟然會(huì)發(fā)生 Server 的數(shù)量比 Client 的數(shù)量多的情況。
我很可憐這些 Proxy 們,他們活的太累了。但由于 Proxy 的工作特性,只需要進(jìn)行完整的轉(zhuǎn)發(fā)即可完成工作,不需要思考--自然有一頭烏黑油亮的秀發(fā)。
加上 Nginx 工程師可以很容易打破 35 歲魔咒,所以這個(gè)職業(yè)依然讓人趨之若鶩。你也想做一枚 Nginx 工程師么?
如何保證 Nginx 的高可用?
目前 HTTP 協(xié)議,乃至 WebSocket 協(xié)議,乃至采用了 MQTT 協(xié)議的 WebSocket 協(xié)議,都不可避免的使用了 Nginx。
所謂病從口入,禍從口出。作為入口,Nginx 承擔(dān)的責(zé)任非常的重要。假如某個(gè)時(shí)刻不能用了,那可真是災(zāi)難。
如何保證 Nginx 的高可用呢?這是個(gè)問(wèn)題。不論你用什么樣的方案,到最后總是要?dú)w為單一,很讓人苦惱。
所謂的高可用,無(wú)非兩種方式:
- 一種方式就是在組件自身上做文章。
- 另外一種方式,就是加入一個(gè)中間層。
我們通常希望在高可用的時(shí)候,同時(shí)還能夠負(fù)載均衡,典型的貓和狗都想要,貪婪的很。
每當(dāng)解決不了問(wèn)題的時(shí)候,我們都會(huì)加入一個(gè)中間層,然后把希望寄托在這個(gè)新生的組件上。
如果這個(gè)中間層解決不了問(wèn)題,我們就可以加入另外一個(gè)中間層。就這樣一層套一層,到最后系統(tǒng)高可用架構(gòu)就會(huì)變得非常復(fù)雜。
DNS 保證高可用
第一種方式當(dāng)然是要在 DNS 上做文章了。通過(guò)在 DNS 上,綁定多個(gè) Nginx 的 IP 地址,即可完成高可用。不僅能夠完成高可用,還能順便完成負(fù)載均衡。
但這玩意有一個(gè)致命的問(wèn)題,那就是故障的感知時(shí)間。
我們的瀏覽器在訪問(wèn)到真正的 Nginx 之前,需要把域名轉(zhuǎn)化為真正的 IP 地址,DNS 就是干解析這個(gè)動(dòng)作的,每次需要耗費(fèi) 20-20ms 不等。
為了加快解析速度,一般都會(huì)有多級(jí)的緩存。比如瀏覽器就有 DNS 的緩存;你使用的 PC 機(jī)上也有這樣的緩存;IPS 服務(wù)提供商,也會(huì)有緩存;再加上有的企業(yè)為了加速訪問(wèn)所自建的 DNS 服務(wù)器,中間的緩存層就更多了。
只有所有的緩存都不命中的情況下,DNS 才會(huì)查詢真正的 IP 地址。所以,如果有一臺(tái) Nginx 宕機(jī)了,這個(gè)故障的感知能力就會(huì)特別的差??傆幸徊糠钟脩舻恼?qǐng)求,會(huì)落在這臺(tái)已經(jīng)死亡的機(jī)器上。
硬件保證高可用
我們前面說(shuō)了。解決不了的問(wèn)題,就可以加中間層,即使這個(gè)中間層是硬件,比如 F5。
這種架構(gòu)一般的企業(yè)玩不起,只有那些采購(gòu)有回扣有油水的公司,才會(huì)喜歡這個(gè)。互聯(lián)網(wǎng)中用的很少,就不過(guò)多介紹了。
當(dāng)然,F(xiàn)5 同樣有單點(diǎn)的問(wèn)題。雖然硬件肯定要比軟件穩(wěn)定上一點(diǎn),但是總歸是一個(gè)隱患。
就像 Oracle 無(wú)論再厲害,它還是有出問(wèn)題的時(shí)候,到時(shí)候備機(jī)是必須的。有的廠商在賣(mài)硬件的時(shí)候,推薦你一次買(mǎi) 3 個(gè)!為啥呢?這也有理由。
你的一臺(tái)硬件正在服務(wù),有兩臺(tái)備份機(jī)器。當(dāng)你服務(wù)的這臺(tái)機(jī)器出現(xiàn)問(wèn)題時(shí),就可以選取備份機(jī)中的其中一臺(tái)作為主機(jī),另一臺(tái)依然是備機(jī),集群還是高可用的。
這理由真讓人陶醉。按照這個(gè)邏輯,碰到傻子,我可以賣(mài)出 100 臺(tái)!
①主備模式
硬的不行,就要來(lái)軟的。采用主備的模式,使用軟件來(lái)完成切換過(guò)程。
如圖,使用 Keepalived 組件,通過(guò) VRRP 協(xié)議,即可完成最簡(jiǎn)單的高可用配置。
我們把 DNS 的地址綁定在 VIP 上,當(dāng)正在服務(wù)的 Nginx 發(fā)生問(wèn)題,VIP 會(huì)發(fā)生漂移,轉(zhuǎn)移到另外一臺(tái) Nginx 上。
可以看到,備份的 Nginx,正常情況下是無(wú)法進(jìn)行服務(wù)的,它也叫做影子節(jié)點(diǎn),只有主 Nginx 發(fā)生問(wèn)題的時(shí)候才有用。如果你的節(jié)點(diǎn)非常多,這種模式下,會(huì)有非常大的浪費(fèi)。
除了浪費(fèi),還有一個(gè)非常大的問(wèn)題。那就是,單臺(tái) Nginx 無(wú)論性能多么牛 X,總是有上限的。當(dāng)網(wǎng)卡的流量達(dá)到頂峰,接下來(lái)何去何從呢?
這種模式肯定是不滿足需求的。
②簡(jiǎn)單組合模式
這個(gè)時(shí)候,我們就可以配合 DNS 解析,以及主備模式做文章了。如下圖,DNS 解析到兩個(gè) VIP 上,VIP 本身也做了高可用。
這樣就能夠縮短故障時(shí)間,同時(shí)也能夠保證每個(gè)組件的高可用。
這種架構(gòu)模式思路是非常清晰的,但依然存在影子節(jié)點(diǎn)的浪費(fèi)。
③LVS+KeepAlived+Nginx
LVS 是 Linux Virtual Server 的簡(jiǎn)稱,也就是 Linux 虛擬服務(wù)器。
現(xiàn)在 LVS 已經(jīng)是 Linux 標(biāo)準(zhǔn)內(nèi)核的一部分,從 Linux2.4 內(nèi)核以后,已經(jīng)完全內(nèi)置了 LVS 的各個(gè)功能模塊,無(wú)需給內(nèi)核打任何補(bǔ)丁,可以直接使用 LVS 提供的各種功能。
LVS 工作在 OSI 模型的第四層:傳輸層,比如 TCP/UDP,所以像七層網(wǎng)絡(luò)的 HTTP 協(xié)議,它是識(shí)別不出來(lái)的。
也就是說(shuō),我們不能拿 HTTP 協(xié)議的一些內(nèi)容來(lái)控制路由,它的路由切入層次更低一些。
如下圖,LVS 架設(shè)的服務(wù)器集群系統(tǒng)有三個(gè)部分組成:
- 最前端的負(fù)載均衡層,用 Load Balancer 表示。
- 中間的服務(wù)器集群層,用 Server Array 表示。
- 最底端的數(shù)據(jù)共享存儲(chǔ)層,用 Shared Storage 表示。
DR(直接路由)模式可將響應(yīng)數(shù)據(jù)包直接返回給用戶瀏覽器,避免負(fù)載均衡服務(wù)器網(wǎng)卡帶寬成為瓶頸,是目前采用最為廣泛的方式(數(shù)據(jù)不詳,F(xiàn)ullnat 模式使用也比較廣泛)。
所以,配合 DNS 的負(fù)載均衡,加上 LVS 的負(fù)載均衡,可以實(shí)現(xiàn)雙層的負(fù)載均衡和高可用。
如圖,DNS 可以將請(qǐng)求綁定在 VIP 上。由于 LVS DR 模式的效率非常高,網(wǎng)卡要達(dá)到瓶頸也需要非常大的請(qǐng)求量(只有入口流量才走 LVS),所以一般通過(guò) LVS 做 Nginx 的負(fù)載均衡就足夠了。
如果 LVS 還有瓶頸,那么就可以在 DNS 上再做文章。
還有哪些挑戰(zhàn)?其實(shí),我們上面談到的這些方案,大多數(shù)是在同機(jī)房的。如果在多個(gè)機(jī)房,如何讓用戶選擇最快的節(jié)點(diǎn)、如何保證負(fù)載均衡,又是一個(gè)大的問(wèn)題。
另外,你可以看到數(shù)據(jù)包經(jīng)過(guò)層層的轉(zhuǎn)發(fā)和協(xié)調(diào),還有多種負(fù)載均衡算法參與其中,如何保持會(huì)話,也是一個(gè)挑戰(zhàn)。
一般的,四層會(huì)話會(huì)通過(guò) IP 地址去實(shí)現(xiàn),七層會(huì)話會(huì)通過(guò) Cookie 或者頭信息等去實(shí)現(xiàn)。
開(kāi)發(fā)人員一般情況下接觸不到這么入口級(jí)的東西,但一旦遇到了,可能會(huì)受忙腳亂。
本文是我根據(jù)一些即有的經(jīng)驗(yàn)進(jìn)行整理,希望你在公司需要一些高可用方案的時(shí)候,能夠助你一臂之力。
PS:什么叫方案?你只需要當(dāng)時(shí)把你的領(lǐng)導(dǎo)哄好,讓他感覺(jué)很認(rèn)同的樣子就行了。至于要不要做,具體怎么做,那都是后面的事。
君不見(jiàn),扯了這么半天,很多企業(yè)其實(shí)一個(gè) Nginx,就可以走天下。
作者:小姐姐味道
簡(jiǎn)介:聚焦基礎(chǔ)架構(gòu)和 Linux。十年架構(gòu),日百億流量,與你探討高并發(fā)世界,給你不一樣的味道。
編輯:陶家龍
出處:轉(zhuǎn)載自公眾號(hào)小姐姐味道(ID:xjjdog)