引言
隨著移動(dòng)互聯(lián)網(wǎng)的瘋長式發(fā)展,互聯(lián)網(wǎng)公司開始因?yàn)樽陨懋a(chǎn)品的用戶指數(shù)級(jí)增長的同時(shí),內(nèi)心是復(fù)雜的.用戶量的增加往往會(huì)給自己的產(chǎn)品提升知名度和經(jīng)濟(jì)效益.另一方面,超大用戶訪問量也給系統(tǒng)的維護(hù)和開始帶來了挑戰(zhàn).目前國內(nèi)面臨著巨大高并發(fā)的企業(yè)典型的有兩家,12306和阿里的各種購物狂歡節(jié).2011年的時(shí)候12306還在春運(yùn)時(shí)遭到廣大刷票黨的吐槽,到15年的今天,12306一點(diǎn)一點(diǎn)的在進(jìn)步著.而淘寶每年的雙11一天的進(jìn)賬就是千億級(jí),這么大的用戶訪問量是如何做到服務(wù)器不當(dāng)機(jī)的呢.這里涉及到一個(gè)非常典型的問題,一臺(tái)再好的服務(wù)器,帶寬再強(qiáng)大也無法保證上億的用戶同時(shí)訪問,可以說服務(wù)器是一個(gè)高并發(fā)時(shí)的瓶頸,如何解決這個(gè)瓶頸?阿里和12306是怎么克服這個(gè)問題的呢?作為開始工程師,我對此十分感興趣,做了一些研究,并用Cisco Packet做了簡單的模擬.
在進(jìn)一步解決服務(wù)器瓶頸問題之前,需要有具備一些基礎(chǔ)的計(jì)算機(jī)網(wǎng)絡(luò)知識(shí),理解這些基本概念.這是解決高并發(fā)問題的一個(gè)基本前提,離開這個(gè)根基,去談集群就是耍流氓.
知識(shí)準(zhǔn)備
- 計(jì)算機(jī)兩種分層結(jié)構(gòu)OSI和ISO
- IP地址/子網(wǎng)掩碼
- 網(wǎng)關(guān)/默認(rèn)網(wǎng)關(guān)
- TCP連接的三次握手與四次分手
- 數(shù)據(jù)包/mac地址/端口號(hào)
- 路由器
- 交換機(jī)
- 網(wǎng)卡
互聯(lián)網(wǎng)中計(jì)算機(jī)間的通信
名詞解釋
host1 --- 主機(jī)1(可以理解成互聯(lián)網(wǎng)中做任意一臺(tái)電腦)
host2 --- 主機(jī)2
host3 --- 主機(jī)3
switcher1 --- 交換機(jī)(物理設(shè)備,二層,只看目標(biāo)與源的mac地址與端口)
router1 --- 路由器(三層,看目標(biāo)與源的IP地址)
網(wǎng)卡 --- 物理設(shè)備,維護(hù)著一個(gè)IP地址,該地址與一個(gè)mac地址是綁定關(guān)系.
任意兩臺(tái)主機(jī)想要通信,需要先互發(fā)數(shù)據(jù)包,進(jìn)行三次握手,成功建立連接后,再由請求主機(jī)向目標(biāo)主機(jī)發(fā)送數(shù)據(jù)包.這是一個(gè)互聯(lián)網(wǎng)請求的大前提.
假如有一臺(tái)主機(jī)host1, 它本地維護(hù)著一張路由表,數(shù)據(jù)結(jié)構(gòu)如下
host1與host2通信
Step1: 確認(rèn)要發(fā)送的數(shù)據(jù)包三大內(nèi)容,mac地址,IP地址,端口.
Step2: 發(fā)送數(shù)據(jù)包建立進(jìn)行三次握手,這是關(guān)于最小網(wǎng)絡(luò)連接的導(dǎo)圖.一個(gè)簡單的http請求,必須完成的最小粒度應(yīng)該是三次握手---數(shù)據(jù)---四次分手.只有雙方主機(jī)都確認(rèn)分手以后,客戶端才會(huì)釋放本次連接使用的端口號(hào),以節(jié)省資源.
Step3: 發(fā)送真實(shí)數(shù)據(jù),下圖顯示了其發(fā)送數(shù)據(jù)的過程.圖中host1與host2處于同一個(gè)網(wǎng)段中,中間只連了一臺(tái)交換機(jī),于是直接將數(shù)據(jù)包扔給交換機(jī),交換機(jī)通過物理網(wǎng)卡收發(fā)數(shù)據(jù),這個(gè)速度無疑是非惩埽快的.具體過程下圖有詳細(xì)說明.
host1與Host3通信
step1與step2同上.
step3:host1與host3不在同一個(gè)網(wǎng)段,因此在確認(rèn)數(shù)據(jù)包時(shí),需要取網(wǎng)關(guān)的mac地址;此后host1將請求數(shù)據(jù)扔給肉頭,也就是router1.這后router1要做的事情是重復(fù)操作step1,step2,step3,直到找到目標(biāo)主機(jī).如果目標(biāo)主機(jī)根本不存在,那么連接會(huì)超時(shí).過程分析圖如下.
服務(wù)器的瓶頸
設(shè)計(jì)一個(gè)極簡單的web網(wǎng)站, 很容易搭建一臺(tái)服務(wù)器,上面放著用戶可能需要的所有資源文件,圖片,視頻和日記等等.這個(gè)模型實(shí)現(xiàn)了非常簡單的網(wǎng)絡(luò)結(jié)構(gòu),效果顯著.但也存在問題,當(dāng)你在為網(wǎng)站做了大量推廣時(shí)后,用戶量猛增,同一時(shí)間的訪問量跟著漲起來,保持一天增1000個(gè)(假設(shè)這個(gè)網(wǎng)站做的不錯(cuò),用戶不會(huì)流失),那么三個(gè)月后,這臺(tái)服務(wù)器變得力不從心.用戶關(guān)于訪問頁面總是404的一系列負(fù)面反饋也日益頻繁.這就是高并發(fā)形成的服務(wù)器瓶頸.
這個(gè)現(xiàn)象揭示了兩個(gè)問題
- 用戶訪問量大的時(shí)候,服務(wù)器甚至都無法保證與每個(gè)請求建立連接.
- 同樣是高并發(fā),一臺(tái)服務(wù)器畢竟只能提供有限的IO,終究導(dǎo)致往外寫數(shù)據(jù)十分緩慢.
解決辦法1
既然一臺(tái)服務(wù)器已經(jīng)無法滿足海量用戶的訪問,那么就多買幾臺(tái)服務(wù)器好了.話說顧客是上帝,互聯(lián)網(wǎng)時(shí)代,用戶群就是王道,一切為用戶.
不幸的是問題依然存在.比如:
- 你有多臺(tái)服務(wù)器,用戶請求的地址始終都是同一個(gè)域名這個(gè)請求最終該由哪臺(tái)服務(wù)器響應(yīng)呢?
- 即使現(xiàn)在的域名解析支持一個(gè)域名綁定多個(gè)IP地址.那這個(gè)IP地址就必須是公網(wǎng)IP,而公網(wǎng)IP資源有限,一臺(tái)服務(wù)器一個(gè)公網(wǎng)IP,顯然不是良策.
解決辦法2
既然不能用公網(wǎng)IP,那么就在這些服務(wù)器與客戶端之間再搭一臺(tái)中間服務(wù)器,這臺(tái)服務(wù)器負(fù)責(zé)持有公網(wǎng)IP,然后將用戶請求的數(shù)據(jù)轉(zhuǎn)發(fā)給其后的真實(shí)負(fù)服務(wù)器,即可.
這種解決方案,會(huì)遇到一個(gè)網(wǎng)絡(luò)技術(shù)問題.
用戶在發(fā)送請求時(shí),首先會(huì)給中間服務(wù)器發(fā)送數(shù)據(jù)包,進(jìn)行三次握手,這個(gè)過程建立連接的是用戶與中間服務(wù)器.這就會(huì)導(dǎo)致負(fù)載服務(wù)器給用戶發(fā)送響應(yīng)數(shù)據(jù)時(shí),被用戶認(rèn)為是不合法的連接,將被用戶丟棄.
解決辦法3
其實(shí)這個(gè)問題在實(shí)際生活中,早在1998年國內(nèi)就有人提出了解決方案,那就是章文嵩士提出的LVS虛擬服務(wù)器.
它是這么解決的.
中間服務(wù)器D(10.211.55.2)收到用戶C1(192.168.1.100)的請求數(shù)據(jù)包后,只是拆包,將目標(biāo)的mac地址修改到自己網(wǎng)段中一臺(tái)真實(shí)服務(wù)器RS1,然后將數(shù)據(jù)包打好后發(fā)給RS1.
這臺(tái)RS1收到數(shù)據(jù)后,判斷請求信息,其中源信息和目標(biāo)信息本地都擁有,于是給予自己直接給用戶發(fā)送確認(rèn)連接.而收到請求的用戶C1,再次向中間服務(wù)器D發(fā)送確認(rèn)連接的數(shù)據(jù)包.最終建立TCP連接的是C1與RS1.這樣就使得RS的收發(fā)數(shù)據(jù)變得合理合法與高效.
這就是著名的LVS(Linux Virtual Server).
結(jié)束語
有幸的是LVS被Linux內(nèi)核收錄,只要你的主機(jī)上運(yùn)行著Linux內(nèi)核,就自帶有LVS軟件服務(wù),這很容易讓有需求了解LVS的人自己動(dòng)手搭一個(gè)集群,模擬這種負(fù)載均衡技術(shù).
這將在明天的博文中更新,會(huì)有大概三種LVS實(shí)現(xiàn)方式.