漫談 HTTP 連接

原文鏈接:https://www.cnblogs.com/huansky/p/14221846.html

HTTP 的特點(diǎn)

所以接下來(lái)先是聊聊 HTTP 協(xié)議的特點(diǎn)趴俘、優(yōu)點(diǎn)和缺點(diǎn)。既要看到它好的一面胰蝠,也要正視它不好的一面,只有全方位、多角度了解 HTTP玲献,才能實(shí)現(xiàn)“揚(yáng)長(zhǎng)避短”廓啊,更好地利用 HTTP。

靈活可擴(kuò)展

首先乾胶, HTTP 協(xié)議是一個(gè)“靈活可擴(kuò)展”的傳輸協(xié)議抖剿。

HTTP 協(xié)議最初誕生的時(shí)候就比較簡(jiǎn)單,本著開(kāi)放的精神只規(guī)定了報(bào)文的基本格式识窿,比如用空格分隔單詞斩郎,用換行分隔字段,“header+body”等喻频,報(bào)文里的各個(gè)組成部分都沒(méi)有做嚴(yán)格的語(yǔ)法語(yǔ)義限制缩宜,可以由開(kāi)發(fā)者任意定制。

所以,HTTP 協(xié)議就隨著互聯(lián)網(wǎng)的發(fā)展一同成長(zhǎng)起來(lái)了锻煌。在這個(gè)過(guò)程中妓布,HTTP 協(xié)議逐漸增加了請(qǐng)求方法、版本號(hào)宋梧、狀態(tài)碼匣沼、頭字段等特性。而 body 也不再限于文本形式的 TXT 或 HTML乃秀,而是能夠傳輸圖片肛著、音頻視頻等任意數(shù)據(jù),這些都是源于它的“靈活可擴(kuò)展”的特點(diǎn)跺讯。

而那些 RFC 文檔枢贿,實(shí)際上也可以理解為是對(duì)已有擴(kuò)展的“承認(rèn)和標(biāo)準(zhǔn)化”,實(shí)現(xiàn)了“從實(shí)踐中來(lái)刀脏,到實(shí)踐中去”的良性循環(huán)局荚。

也正是因?yàn)檫@個(gè)特點(diǎn),HTTP 才能在三十年的歷史長(zhǎng)河中“屹立不倒”愈污,從最初的低速實(shí)驗(yàn)網(wǎng)絡(luò)發(fā)展到現(xiàn)在的遍布全球的高速互聯(lián)網(wǎng)耀态,始終保持著旺盛的生命力。

可靠傳輸

第二個(gè)特點(diǎn)暂雹, HTTP 協(xié)議是一個(gè)“可靠”的傳輸協(xié)議首装。

這個(gè)特點(diǎn)顯而易見(jiàn),因?yàn)?HTTP 協(xié)議是基于 TCP/IP 的杭跪,而 TCP 本身是一個(gè)“可靠”的傳輸協(xié)議仙逻,所以 HTTP 自然也就繼承了這個(gè)特性,能夠在請(qǐng)求方和應(yīng)答方之間“可靠”地傳輸數(shù)據(jù)涧尿。

它的具體做法與 TCP/UDP 差不多系奉,都是對(duì)實(shí)際傳輸?shù)臄?shù)據(jù)(entity)做了一層包裝,加上一個(gè)頭姑廉,然后調(diào)用 Socket API缺亮,通過(guò) TCP/IP 協(xié)議棧發(fā)送或者接收。

不過(guò)我們必須正確地理解“可靠”的含義桥言,HTTP 并不能 100% 保證數(shù)據(jù)一定能夠發(fā)送到另一端萌踱,在網(wǎng)絡(luò)繁忙、連接質(zhì)量差等惡劣的環(huán)境下号阿,也有可能收發(fā)失敗虫蝶。“可靠”只是向使用者提供了一個(gè)“承諾”倦西,會(huì)在下層用多種手段“盡量”保證數(shù)據(jù)的完整送達(dá)能真。

當(dāng)然,如果遇到光纖被意外挖斷這樣的極端情況,即使是神仙也不能發(fā)送成功粉铐。所以疼约,“可靠”傳輸是指在網(wǎng)絡(luò)基本正常的情況下數(shù)據(jù)收發(fā)必定成功,借用運(yùn)維里的術(shù)語(yǔ)蝙泼,大概就是“3 個(gè) 9”或者“4 個(gè) 9”的程度吧程剥。

應(yīng)用層協(xié)議

第三個(gè)特點(diǎn),HTTP 協(xié)議是一個(gè)應(yīng)用層的協(xié)議汤踏。

這個(gè)特點(diǎn)也是不言自明的织鲸,但卻很重要。

在 TCP/IP 誕生后的幾十年里溪胶,雖然出現(xiàn)了許多的應(yīng)用層協(xié)議搂擦,但它們都僅關(guān)注很小的應(yīng)用領(lǐng)域,局限在很少的應(yīng)用場(chǎng)景哗脖。例如 FTP 只能傳輸文件瀑踢、SMTP 只能發(fā)送郵件、SSH 只能遠(yuǎn)程登錄等才避,在通用的數(shù)據(jù)傳輸方面“完全不能打”橱夭。

所以 HTTP 憑借著可攜帶任意頭字段和實(shí)體數(shù)據(jù)的報(bào)文結(jié)構(gòu),以及連接控制桑逝、緩存代理等方便易用的特性棘劣,一出現(xiàn)就“技?jí)喝盒邸保杆俪蔀榱藨?yīng)用層里的“明星”協(xié)議楞遏。只要不太苛求性能茬暇,HTTP 幾乎可以傳遞一切東西,滿足各種需求橱健,稱得上是一個(gè)“萬(wàn)能”的協(xié)議。

套用一個(gè)網(wǎng)上流行的段子沙廉,HTTP 完全可以用開(kāi)玩笑的口吻說(shuō):“不要誤會(huì)拘荡,我不是針對(duì) FTP,我是說(shuō)在座的應(yīng)用層各位撬陵,都是垃圾珊皿。”

請(qǐng)求 - 應(yīng)答

第四個(gè)特點(diǎn)巨税,HTTP 協(xié)議使用的是請(qǐng)求 - 應(yīng)答通信模式蟋定。

這個(gè)請(qǐng)求 - 應(yīng)答模式是 HTTP 協(xié)議最根本的通信模型,通俗來(lái)講就是“一發(fā)一收”“有來(lái)有去”草添,就像是寫(xiě)代碼時(shí)的函數(shù)調(diào)用驶兜,只要填好請(qǐng)求頭里的字段,“調(diào)用”后就會(huì)收到答復(fù)。

請(qǐng)求 - 應(yīng)答模式也明確了 HTTP 協(xié)議里通信雙方的定位抄淑,永遠(yuǎn)是請(qǐng)求方先發(fā)起連接和請(qǐng)求屠凶,是主動(dòng)的,而應(yīng)答方只有在收到請(qǐng)求后才能答復(fù)肆资,是被動(dòng)的矗愧,如果沒(méi)有請(qǐng)求時(shí)不會(huì)有任何動(dòng)作。

當(dāng)然郑原,請(qǐng)求方和應(yīng)答方的角色也不是絕對(duì)的唉韭,在瀏覽器 - 服務(wù)器的場(chǎng)景里,通常服務(wù)器都是應(yīng)答方犯犁,但如果將它用作代理連接后端服務(wù)器属愤,那么它就可能同時(shí)扮演請(qǐng)求方和應(yīng)答方的角色。

HTTP 的請(qǐng)求 - 應(yīng)答模式也恰好契合了傳統(tǒng)的 C/S(Client/Server)系統(tǒng)架構(gòu)栖秕,請(qǐng)求方作為客戶端春塌、應(yīng)答方作為服務(wù)器。所以簇捍,隨著互聯(lián)網(wǎng)的發(fā)展就出現(xiàn)了 B/S(Browser/Server)架構(gòu)只壳,用輕量級(jí)的瀏覽器代替笨重的客戶端應(yīng)用,實(shí)現(xiàn)零維護(hù)的“瘦”客戶端暑塑,而服務(wù)器則擯棄私有通信協(xié)議轉(zhuǎn)而使用 HTTP 協(xié)議吼句。

此外,請(qǐng)求 - 應(yīng)答模式也完全符合 RPC(Remote Procedure Call)的工作模式事格,可以把 HTTP 請(qǐng)求處理封裝成遠(yuǎn)程函數(shù)調(diào)用惕艳,導(dǎo)致了 WebService、RESTful 和 gPRC 等的出現(xiàn)驹愚。

無(wú)狀態(tài)

第五個(gè)特點(diǎn)远搪,HTTP 協(xié)議是無(wú)狀態(tài)的。

這個(gè)所謂的“狀態(tài)”應(yīng)該怎么理解呢逢捺?

“狀態(tài)”其實(shí)就是客戶端或者服務(wù)器里保存的一些數(shù)據(jù)或者標(biāo)志谁鳍,記錄了通信過(guò)程中的一些變化信息。

你一定知道劫瞳,TCP 協(xié)議是有狀態(tài)的倘潜,一開(kāi)始處于 CLOSED 狀態(tài),連接成功后是 ESTABLISHED 狀態(tài)志于,斷開(kāi)連接后是 FIN-WAIT 狀態(tài)涮因,最后又是 CLOSED 狀態(tài)。

這些“狀態(tài)”就需要 TCP 在內(nèi)部用一些數(shù)據(jù)結(jié)構(gòu)去維護(hù)伺绽,可以簡(jiǎn)單地想象成是個(gè)標(biāo)志量养泡,標(biāo)記當(dāng)前所處的狀態(tài)嗜湃,例如 0 是 CLOSED,2 是 ESTABLISHED 等等瓤荔。

再來(lái)看 HTTP净蚤,那么對(duì)比一下 TCP 就看出來(lái)了,在整個(gè)協(xié)議里沒(méi)有規(guī)定任何的“狀態(tài)”输硝,客戶端和服務(wù)器永遠(yuǎn)是處在一種“無(wú)知”的狀態(tài)今瀑。建立連接前兩者互不知情,每次收發(fā)的報(bào)文也都是互相獨(dú)立的点把,沒(méi)有任何的聯(lián)系橘荠。收發(fā)報(bào)文也不會(huì)對(duì)客戶端或服務(wù)器產(chǎn)生任何影響,連接后也不會(huì)要求保存任何信息郎逃。

“無(wú)狀態(tài)”形象地來(lái)說(shuō)就是“沒(méi)有記憶能力”哥童。比如,瀏覽器發(fā)了一個(gè)請(qǐng)求褒翰,說(shuō)“我是小明贮懈,請(qǐng)給我 A 文件∮叛担”朵你,服務(wù)器收到報(bào)文后就會(huì)檢查一下權(quán)限,看小明確實(shí)可以訪問(wèn) A 文件揣非,于是把文件發(fā)回給瀏覽器抡医。接著瀏覽器還想要 B 文件,但服務(wù)器不會(huì)記錄剛才的請(qǐng)求狀態(tài)早敬,不知道第二個(gè)請(qǐng)求和第一個(gè)請(qǐng)求是同一個(gè)瀏覽器發(fā)來(lái)的忌傻,所以瀏覽器必須還得重復(fù)一次自己的身份才行:“我是剛才的小明,請(qǐng)?jiān)俳o我 B 文件搞监∷ⅲ”

我們可以再對(duì)比一下 UDP 協(xié)議,不過(guò)它是無(wú)連接也無(wú)狀態(tài)的琐驴,順序發(fā)包亂序收包俘种,數(shù)據(jù)包發(fā)出去后就不管了,收到后也不會(huì)順序整理棍矛。而 HTTP 是有連接無(wú)狀態(tài)安疗,順序發(fā)包順序收包抛杨,按照收發(fā)的順序管理報(bào)文够委。

但不要忘了 HTTP 是“靈活可擴(kuò)展”的,雖然標(biāo)準(zhǔn)里沒(méi)有規(guī)定“狀態(tài)”怖现,但完全能夠在協(xié)議的框架里給它“打個(gè)補(bǔ)丁”茁帽,增加這個(gè)特性玉罐。

其他特點(diǎn)

除了以上的五大特點(diǎn),其實(shí) HTTP 協(xié)議還可以列出非常多的特點(diǎn)潘拨,例如傳輸?shù)膶?shí)體數(shù)據(jù)可緩存可壓縮吊输、可分段獲取數(shù)據(jù)、支持身份認(rèn)證铁追、支持國(guó)際化語(yǔ)言等季蚂。但這些并不能算是 HTTP 的基本特點(diǎn),因?yàn)檫@都是由第一個(gè)“靈活可擴(kuò)展”的特點(diǎn)所衍生出來(lái)的琅束。

小結(jié)

  1. HTTP 是靈活可擴(kuò)展的扭屁,可以任意添加頭字段實(shí)現(xiàn)任意功能;

  2. HTTP 是可靠傳輸協(xié)議涩禀,基于 TCP/IP 協(xié)議“盡量”保證數(shù)據(jù)的送達(dá)料滥;

  3. HTTP 是應(yīng)用層協(xié)議,比 FTP艾船、SSH 等更通用功能更多葵腹,能夠傳輸任意數(shù)據(jù);

  4. HTTP 使用了請(qǐng)求 - 應(yīng)答模式屿岂,客戶端主動(dòng)發(fā)起請(qǐng)求践宴,服務(wù)器被動(dòng)回復(fù)請(qǐng)求;

  5. HTTP 本質(zhì)上是無(wú)狀態(tài)的雁社,每個(gè)請(qǐng)求都是互相獨(dú)立浴井、毫無(wú)關(guān)聯(lián)的,協(xié)議不要求客戶端或服務(wù)器記錄請(qǐng)求相關(guān)的信息霉撵。

HTTP的連接管理

HTTP 的連接管理也算得上是個(gè)“老生常談”的話題了磺浙,你一定曾經(jīng)聽(tīng)說(shuō)過(guò)“短連接”“長(zhǎng)連接”之類的名詞,今天讓我們一起來(lái)把它們弄清楚徒坡。

短連接

HTTP 協(xié)議最初(0.9/1.0)是個(gè)非常簡(jiǎn)單的協(xié)議撕氧,通信過(guò)程也采用了簡(jiǎn)單的“請(qǐng)求 - 應(yīng)答”方式。

它底層的數(shù)據(jù)傳輸基于 TCP/IP喇完,每次發(fā)送請(qǐng)求前需要先與服務(wù)器建立連接伦泥,收到響應(yīng)報(bào)文后會(huì)立即關(guān)閉連接。

因?yàn)榭蛻舳伺c服務(wù)器的整個(gè)連接過(guò)程很短暫锦溪,不會(huì)與服務(wù)器保持長(zhǎng)時(shí)間的連接狀態(tài)不脯,所以就被稱為“短連接”(short-lived connections)。早期的 HTTP 協(xié)議也被稱為是“無(wú)連接”的協(xié)議刻诊。

短連接的缺點(diǎn)相當(dāng)嚴(yán)重防楷,因?yàn)樵?TCP 協(xié)議里,建立連接和關(guān)閉連接都是非吃蜓模“昂貴”的操作复局。TCP 建立連接要有“三次握手”冲簿,發(fā)送 3 個(gè)數(shù)據(jù)包,需要 1 個(gè) RTT亿昏;關(guān)閉連接是“四次揮手”峦剔,4 個(gè)數(shù)據(jù)包需要 2 個(gè) RTT。

而 HTTP 的一次簡(jiǎn)單“請(qǐng)求 - 響應(yīng)”通常只需要 4 個(gè)包角钩,如果不算服務(wù)器內(nèi)部的處理時(shí)間吝沫,最多是 2 個(gè) RTT。這么算下來(lái)递礼,浪費(fèi)的時(shí)間就是“3÷5=60%”野舶,有三分之二的時(shí)間被浪費(fèi)掉了,傳輸效率低得驚人宰衙。

單純地從理論上講平道,TCP 協(xié)議你可能還不太好理解,我就拿打卡考勤機(jī)來(lái)做個(gè)形象的比喻吧供炼。

假設(shè)你的公司買了一臺(tái)打卡機(jī)一屋,放在前臺(tái),因?yàn)檫@臺(tái)機(jī)器比較貴袋哼,所以專門做了一個(gè)保護(hù)罩蓋著它冀墨,公司要求每次上下班打卡時(shí)都要先打開(kāi)蓋子,打卡后再蓋上蓋子涛贯。

可是偏偏這個(gè)蓋子非常牢固诽嘉,打開(kāi)關(guān)閉要費(fèi)很大力氣,打卡可能只要 1 秒鐘弟翘,而開(kāi)關(guān)蓋子卻需要四五秒鐘虫腋,大部分時(shí)間都浪費(fèi)在了毫無(wú)意義的開(kāi)關(guān)蓋子操作上了。

可想而知稀余,平常還好說(shuō)悦冀,一到上下班的點(diǎn)在打卡機(jī)前就會(huì)排起長(zhǎng)隊(duì),每個(gè)人都要重復(fù)“開(kāi)蓋 - 打卡 - 關(guān)蓋”的三個(gè)步驟睛琳,你說(shuō)著急不著急盒蟆。

在這個(gè)比喻里,打卡機(jī)就相當(dāng)于服務(wù)器师骗,蓋子的開(kāi)關(guān)就是 TCP 的連接與關(guān)閉历等,而每個(gè)打卡的人就是 HTTP 請(qǐng)求,很顯然辟癌,短連接的缺點(diǎn)嚴(yán)重制約了服務(wù)器的服務(wù)能力寒屯,導(dǎo)致它無(wú)法處理更多的請(qǐng)求。

長(zhǎng)連接

針對(duì)短連接暴露出的缺點(diǎn)愿待,HTTP 協(xié)議就提出了“長(zhǎng)連接”的通信方式浩螺,也叫“持久連接”(persistent connections)、“連接比越模活”(keep alive)要出、“連接復(fù)用”(connection reuse)。

其實(shí)解決辦法也很簡(jiǎn)單农渊,用的就是“成本均攤”的思路患蹂,既然 TCP 的連接和關(guān)閉非常耗時(shí)間,那么就把這個(gè)時(shí)間成本由原來(lái)的一個(gè)“請(qǐng)求 - 應(yīng)答”均攤到多個(gè)“請(qǐng)求 - 應(yīng)答”上砸紊。

這樣雖然不能改善 TCP 的連接效率传于,但基于“分母效應(yīng)”,每個(gè)“請(qǐng)求 - 應(yīng)答”的無(wú)效時(shí)間就會(huì)降低不少醉顽,整體傳輸效率也就提高了沼溜。

這里我畫(huà)了一個(gè)短連接與長(zhǎng)連接的對(duì)比示意圖。

在短連接里發(fā)送了三次 HTTP“請(qǐng)求 - 應(yīng)答”游添,每次都會(huì)浪費(fèi) 60% 的 RTT 時(shí)間系草。而在長(zhǎng)連接的情況下,同樣發(fā)送三次請(qǐng)求唆涝,因?yàn)橹辉诘谝淮螘r(shí)建立連接找都,在最后一次時(shí)關(guān)閉連接,所以浪費(fèi)率就是“3÷9≈33%”廊酣,降低了差不多一半的時(shí)間損耗能耻。顯然,如果在這個(gè)長(zhǎng)連接上發(fā)送的請(qǐng)求越多亡驰,分母就越大晓猛,利用率也就越高。

繼續(xù)用剛才的打卡機(jī)的比喻凡辱,公司也覺(jué)得這種反復(fù)“開(kāi)蓋 - 打卡 - 關(guān)蓋”的操作太“反人類”了鞍帝,于是頒布了新規(guī)定,早上打開(kāi)蓋子后就不用關(guān)上了煞茫,可以自由打卡帕涌,到下班后再關(guān)上蓋子。

這樣打卡的效率(即服務(wù)能力)就大幅度提升了续徽,原來(lái)一次打卡需要五六秒鐘蚓曼,現(xiàn)在只要一秒就可以了,上下班時(shí)排長(zhǎng)隊(duì)的景象一去不返钦扭,大家都開(kāi)心纫版。

連接相關(guān)的頭字段

由于長(zhǎng)連接對(duì)性能的改善效果非常顯著,所以在 HTTP/1.1 中的連接都會(huì)默認(rèn)啟用長(zhǎng)連接客情。不需要用什么特殊的頭字段指定其弊,只要向服務(wù)器發(fā)送了第一次請(qǐng)求癞己,后續(xù)的請(qǐng)求都會(huì)重復(fù)利用第一次打開(kāi)的 TCP 連接,也就是長(zhǎng)連接梭伐,在這個(gè)連接上收發(fā)數(shù)據(jù)痹雅。

當(dāng)然,我們也可以在請(qǐng)求頭里明確地要求使用長(zhǎng)連接機(jī)制糊识,使用的字段是 Connection绩社,值是 “keep-alive”。

不過(guò)不管客戶端是否顯式要求長(zhǎng)連接赂苗,如果服務(wù)器支持長(zhǎng)連接愉耙,它總會(huì)在響應(yīng)報(bào)文里放一個(gè) “Connection: keep-alive” 字段,告訴客戶端:“我是支持長(zhǎng)連接的拌滋,接下來(lái)就用這個(gè) TCP 一直收發(fā)數(shù)據(jù)吧”朴沿。

不過(guò)長(zhǎng)連接也有一些小缺點(diǎn),問(wèn)題就出在它的“長(zhǎng)”字上败砂。

因?yàn)?TCP 連接長(zhǎng)時(shí)間不關(guān)閉悯仙,服務(wù)器必須在內(nèi)存里保存它的狀態(tài),這就占用了服務(wù)器的資源吠卷。如果有大量的空閑長(zhǎng)連接只連不發(fā)锡垄,就會(huì)很快耗盡服務(wù)器的資源,導(dǎo)致服務(wù)器無(wú)法為真正有需要的用戶提供服務(wù)祭隔。

所以货岭,長(zhǎng)連接也需要在恰當(dāng)?shù)臅r(shí)間關(guān)閉,不能永遠(yuǎn)保持與服務(wù)器的連接疾渴,這在客戶端或者服務(wù)器都可以做到千贯。

在客戶端,可以在請(qǐng)求頭里加上“Connection: close”字段搞坝,告訴服務(wù)器:“這次通信后就關(guān)閉連接”搔谴。服務(wù)器看到這個(gè)字段,就知道客戶端要主動(dòng)關(guān)閉連接桩撮,于是在響應(yīng)報(bào)文里也加上這個(gè)字段敦第,發(fā)送之后就調(diào)用 Socket API 關(guān)閉 TCP 連接。

服務(wù)器端通常不會(huì)主動(dòng)關(guān)閉連接店量,但也可以使用一些策略芜果。拿 Nginx 來(lái)舉例,它有兩種方式:

  1. 使用“keepalive_timeout”指令融师,設(shè)置長(zhǎng)連接的超時(shí)時(shí)間右钾,如果在一段時(shí)間內(nèi)連接上沒(méi)有任何數(shù)據(jù)收發(fā)就主動(dòng)斷開(kāi)連接,避免空閑連接占用系統(tǒng)資源。

  2. 使用“keepalive_requests”指令舀射,設(shè)置長(zhǎng)連接上可發(fā)送的最大請(qǐng)求次數(shù)窘茁。比如設(shè)置成 1000,那么當(dāng) Nginx 在這個(gè)連接上處理了 1000 個(gè)請(qǐng)求后脆烟,也會(huì)主動(dòng)斷開(kāi)連接山林。

另外,客戶端和服務(wù)器都可以在報(bào)文里附加通用頭字段“Keep-Alive: timeout=value”浩淘,限定長(zhǎng)連接的超時(shí)時(shí)間。但這個(gè)字段的約束力并不強(qiáng)吴攒,通信的雙方可能并不會(huì)遵守张抄,所以不太常見(jiàn)。

隊(duì)頭阻塞

看完了短連接和長(zhǎng)連接洼怔,接下來(lái)就要說(shuō)到著名的“隊(duì)頭阻塞”(Head-of-line blocking署惯,也叫“隊(duì)首阻塞”)了。

“隊(duì)頭阻塞”與短連接和長(zhǎng)連接無(wú)關(guān)镣隶,而是由 HTTP 基本的“請(qǐng)求 - 應(yīng)答”模型所導(dǎo)致的极谊。

因?yàn)?HTTP 規(guī)定報(bào)文必須是“一發(fā)一收”,這就形成了一個(gè)先進(jìn)先出的“串行”隊(duì)列安岂。隊(duì)列里的請(qǐng)求沒(méi)有輕重緩急的優(yōu)先級(jí)轻猖,只有入隊(duì)的先后順序,排在最前面的請(qǐng)求被最優(yōu)先處理域那。

如果隊(duì)首的請(qǐng)求因?yàn)樘幚淼奶⒄`了時(shí)間咙边,那么隊(duì)列里后面的所有請(qǐng)求也不得不跟著一起等待,結(jié)果就是其他的請(qǐng)求承擔(dān)了不應(yīng)有的時(shí)間成本次员。

還是用打卡機(jī)做個(gè)比喻败许。

上班的時(shí)間點(diǎn)上,大家都在排隊(duì)打卡淑蔚,可這個(gè)時(shí)候偏偏最前面的那個(gè)人遇到了打卡機(jī)故障市殷,怎么也不能打卡成功,急得滿頭大汗刹衫。等找人把打卡機(jī)修好醋寝,后面排隊(duì)的所有人全遲到了。

性能優(yōu)化

因?yàn)椤罢?qǐng)求 - 應(yīng)答”模型不能變带迟,所以“隊(duì)頭阻塞”問(wèn)題在 HTTP/1.1 里無(wú)法解決甥桂,只能緩解,有什么辦法呢邮旷?

公司里可以再多買幾臺(tái)打卡機(jī)放在前臺(tái)黄选,這樣大家可以不用擠在一個(gè)隊(duì)伍里,分散打卡,一個(gè)隊(duì)伍偶爾阻塞也不要緊办陷,可以改換到其他不阻塞的隊(duì)伍貌夕。

這在 HTTP 里就是“并發(fā)連接”(concurrent connections),也就是同時(shí)對(duì)一個(gè)域名發(fā)起多個(gè)長(zhǎng)連接民镜,用數(shù)量來(lái)解決質(zhì)量的問(wèn)題啡专。

但這種方式也存在缺陷。如果每個(gè)客戶端都想自己快制圈,建立很多個(gè)連接们童,用戶數(shù)×并發(fā)數(shù)就會(huì)是個(gè)天文數(shù)字。服務(wù)器的資源根本就扛不住鲸鹦,或者被服務(wù)器認(rèn)為是惡意攻擊慧库,反而會(huì)造成“拒絕服務(wù)”。

所以馋嗜,HTTP 協(xié)議建議客戶端使用并發(fā)齐板,但不能“濫用”并發(fā)。RFC2616 里明確限制每個(gè)客戶端最多并發(fā) 2 個(gè)連接葛菇。不過(guò)實(shí)踐證明這個(gè)數(shù)字實(shí)在是太小了甘磨,眾多瀏覽器都“無(wú)視”標(biāo)準(zhǔn),把這個(gè)上限提高到了 6~8眯停。后來(lái)修訂的 RFC7230 也就“順?biāo)浦邸奔糜撸∠诉@個(gè)“2”的限制。

但“并發(fā)連接”所壓榨出的性能也跟不上高速發(fā)展的互聯(lián)網(wǎng)無(wú)止境的需求莺债,還有什么別的辦法嗎吗冤?

公司發(fā)展的太快了,員工越來(lái)越多九府,上下班打卡成了迫在眉睫的大問(wèn)題椎瘟。前臺(tái)空間有限,放不下更多的打卡機(jī)了侄旬,怎么辦肺蔚?那就多開(kāi)幾個(gè)打卡的地方,每個(gè)樓層儡羔、辦公區(qū)的入口也放上三四臺(tái)打卡機(jī)宣羊,把人進(jìn)一步分流,不要都往前臺(tái)擠汰蜘。

這個(gè)就是“域名分片”(domain sharding)技術(shù)仇冯,還是用數(shù)量來(lái)解決質(zhì)量的思路。

HTTP 協(xié)議和瀏覽器不是限制并發(fā)連接數(shù)量嗎族操?好苛坚,那我就多開(kāi)幾個(gè)域名比被,比如shard1.chrono.comshard2.chrono.com泼舱,而這些域名都指向同一臺(tái)服務(wù)器www.chrono.com等缀,這樣實(shí)際長(zhǎng)連接的數(shù)量就又上去了,真是“美滋滋”娇昙。不過(guò)實(shí)在是有點(diǎn)“上有政策尺迂,下有對(duì)策”的味道。

小結(jié)

這一講中我們學(xué)習(xí)了 HTTP 協(xié)議里的短連接和長(zhǎng)連接冒掌,簡(jiǎn)單小結(jié)一下今天的內(nèi)容:

  1. 早期的 HTTP 協(xié)議使用短連接噪裕,收到響應(yīng)后就立即關(guān)閉連接,效率很低股毫;

  2. HTTP/1.1 默認(rèn)啟用長(zhǎng)連接膳音,在一個(gè)連接上收發(fā)多個(gè)請(qǐng)求響應(yīng),提高了傳輸效率皇拣;

  3. 服務(wù)器會(huì)發(fā)送“Connection: keep-alive”字段表示啟用了長(zhǎng)連接严蓖;

  4. 報(bào)文頭里如果有“Connection: close”就意味著長(zhǎng)連接即將關(guān)閉薄嫡;

  5. 過(guò)多的長(zhǎng)連接會(huì)占用服務(wù)器資源氧急,所以服務(wù)器會(huì)用一些策略有選擇地關(guān)閉長(zhǎng)連接;

  6. “隊(duì)頭阻塞”問(wèn)題會(huì)導(dǎo)致性能下降毫深,可以用“并發(fā)連接”和“域名分片”技術(shù)緩解吩坝。


作者:易道云控

鏈接:http://www.reibang.com/p/58ac01ffda82

來(lái)源:簡(jiǎn)書(shū)

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)哑蔫,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處钉寝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市闸迷,隨后出現(xiàn)的幾起案子嵌纲,更是在濱河造成了極大的恐慌,老刑警劉巖腥沽,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逮走,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡今阳,警方通過(guò)查閱死者的電腦和手機(jī)师溅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)盾舌,“玉大人墓臭,你說(shuō)我怎么就攤上這事⊙矗” “怎么了窿锉?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我榆综,道長(zhǎng)妙痹,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任鼻疮,我火速辦了婚禮怯伊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘判沟。我一直安慰自己耿芹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布挪哄。 她就那樣靜靜地躺著吧秕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪迹炼。 梳的紋絲不亂的頭發(fā)上砸彬,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音斯入,去河邊找鬼砂碉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛刻两,可吹牛的內(nèi)容都是我干的增蹭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼磅摹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼滋迈!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起户誓,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饼灿,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后帝美,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體碍彭,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年证舟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了硕旗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡女责,死狀恐怖漆枚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抵知,我是刑警寧澤墙基,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布软族,位于F島的核電站,受9級(jí)特大地震影響残制,放射性物質(zhì)發(fā)生泄漏立砸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一初茶、第九天 我趴在偏房一處隱蔽的房頂上張望颗祝。 院中可真熱鬧,春花似錦恼布、人聲如沸螺戳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)倔幼。三九已至,卻和暖如春爽待,著一層夾襖步出監(jiān)牢的瞬間损同,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工鸟款, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膏燃,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓欠雌,卻偏偏與公主長(zhǎng)得像蹄梢,于是被迫代替她去往敵國(guó)和親疙筹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子富俄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容