書接上文蹲堂,據(jù)說某年某月的某一天,一臺(tái)機(jī)房里普通服務(wù)器贝淤,開了機(jī)柒竞,啟動(dòng)了操作系統(tǒng),隨著操作系統(tǒng)的就緒播聪,服務(wù)器啟動(dòng)了 http 服務(wù)進(jìn)程朽基,這個(gè) http 服務(wù)的守護(hù)進(jìn)程,(daemon)离陶,可能是 apache稼虎,也可能是 nginx,不管怎么說枕磁,這個(gè) http 服務(wù)進(jìn)程開始定位到服務(wù)器上的 www 文件夾渡蜻,一般是位于 /var/www 术吝,然后啟動(dòng)了一些附屬的模塊计济,例如 php_mod,或者排苍,使用 fastcgi 方式連接到 php 的 fpm 管理進(jìn)程沦寂,然后,向操作系統(tǒng)申請(qǐng)了一個(gè) tcp 連接淘衙,然后綁定在了 80 端口传藏,調(diào)用了 accept 函數(shù),開始了默默的監(jiān)聽彤守,監(jiān)聽著可能來自位于地球任何一個(gè)地方的請(qǐng)求毯侦,隨時(shí)準(zhǔn)備做出響應(yīng)。
詳解一次HTTP請(qǐng)求の客戶端
斷點(diǎn)1: 客戶端域名的解析過程
當(dāng)用戶在瀏覽器中輸入www.baidu.com的時(shí)候具垫,域名解析的過程會(huì)經(jīng)過以下過程:(細(xì)節(jié)詳情可參見https://zhidao.baidu.com/question/437513187.html侈离,難得《百度知道》還能有這么正經(jīng)點(diǎn)的答案,嘔吼吼吼~~~)
第1步筝蚕,瀏覽器會(huì)檢查緩存中有沒有這個(gè)域名對(duì)應(yīng)的解析過的IP地址卦碾,如果緩存中有铺坞,這個(gè)解析過程就將結(jié)束。瀏覽器緩存域名也是有大小和時(shí)間(TTL)限制的洲胖。
第2步济榨,如果用戶的瀏覽器緩存中沒有,瀏覽器會(huì)查找操作系統(tǒng)緩存中是否有這個(gè)域名對(duì)應(yīng)的DNS解析結(jié)果绿映。比如在Windows中可以通過C:\Windows\System32\drivers\etc\hosts文件擒滑,如果在這里指定了一個(gè)域名對(duì)應(yīng)的IP地址,那么瀏覽器會(huì)首先使用這個(gè)IP地址(不加任何判斷)绘梦,解析過程也就將結(jié)束橘忱。正是因?yàn)橛羞@種本地DNS解析的規(guī)程,所以黑客或病毒就有可能通過修改你的域名解析來把特定的域名解析到它指定的IP地址上卸奉,導(dǎo)致這些域名被劫持钝诚。
前面這兩個(gè)步驟都是在本機(jī)完成的,還沒有涉及真正的域名解析服務(wù)器(DNS)榄棵,如果在本機(jī)中仍然無法完成域名的解析凝颇,瀏覽器就會(huì)向域名服務(wù)器發(fā)起域名解析請(qǐng)求了。
第3步疹鳄,如何拧略、怎么知道域名服務(wù)器呢?在我們的網(wǎng)絡(luò)配置中都會(huì)有"DNS服務(wù)器地址"這一項(xiàng)瘪弓,據(jù)說Windows下垫蛆,ipconfig即可查看,如下截圖(反正我是沒看到~~)腺怯。操作系統(tǒng)會(huì)把這個(gè)域名發(fā)送給這里設(shè)置的LDNS袱饭,也就是本地區(qū)的域名服務(wù)器。這個(gè)專門的域名解析服務(wù)器會(huì)緩存域名解析結(jié)果呛占,當(dāng)然緩存時(shí)間是受域名的失效時(shí)間控制的虑乖,大約80%的域名解析都到這里就已經(jīng)完成了,所以LDNS主要承擔(dān)了域名的解析工作晾虑。
如果LDNS仍然沒有命中疹味,就直接到Root Server域名服務(wù)器請(qǐng)求解析。帜篇。糙捺。。笙隙。洪灯。。(具體細(xì)節(jié)過程逃沿,改日再敘婴渡,這個(gè)不是重點(diǎn)幻锁。)
總之,dns的域名解析是遞歸的(dns是迭代的)边臼,如果找不到對(duì)應(yīng)域名的ip地址哄尔,就向上轉(zhuǎn)發(fā)請(qǐng)求,然后把得到的這個(gè)域名對(duì)應(yīng)的 nameserver 的地址取得柠并,再向這個(gè) namserver 去請(qǐng)求域名對(duì)應(yīng)的 ip岭接,最后把這個(gè) ip 地址返回給瀏覽器(坐等收菜即可~~~),瀏覽器根據(jù)TTL值緩存在本地系統(tǒng)中臼予,域名解析過程結(jié)束鸣戴。
<( ̄︶ ̄)↗[GO!]
得到服務(wù)器的ip地址后,瀏覽器開始構(gòu)造http請(qǐng)求粘拾,一個(gè)典型的http request header一般需要需要包括請(qǐng)求的方法(共7種)窄锅,例如 GET 或者 POST 等,不常用的還有 PUT 和 DELETE 方法缰雇,更加不常用的還有 HEAD 和 OPTION 以及 TRACE 方法入偷,一般的瀏覽器只能發(fā)起 GET 或者 POST 請(qǐng)求。械哟。疏之。。暇咆。锋爪。好,暫停存檔爸业。
斷點(diǎn)2: HTTP的請(qǐng)求格式
雖然計(jì)算機(jī)網(wǎng)絡(luò)的基礎(chǔ)知識(shí)有其骄,但既然是考究過程,那不妨回憶且掃盲下http請(qǐng)求的典型組成結(jié)構(gòu)吧沃呢。誰讓我們身處網(wǎng)絡(luò)時(shí)代年栓,大神又如此之多呢拆挥,詳細(xì)參解可查看這篇文章薄霜,http://blog.csdn.net/u012125579/article/details/47426737,大神寫的形式暫可達(dá)到掃盲的要求纸兔,我也就是看過惰瓜,并未經(jīng)己手,終究還是“紙上得來終覺淺”汉矿,此事須躬行崎坊,舉個(gè)荔枝~~
客戶端通過發(fā)送HTTP請(qǐng)求向服務(wù)器請(qǐng)求對(duì)資源的訪問,HTTP請(qǐng)求有三部分組成:請(qǐng)求行洲拇、消息頭和消息體:
<request-line>
<headers>
<blank line>
[<request-body>
請(qǐng)求行(Request Line)
請(qǐng)求行有三個(gè)標(biāo)記組成:請(qǐng)求方法? 請(qǐng)求URL? 協(xié)議/版本奈揍,以空格分隔曲尸,比如上圖中的:GET / HTTP/1.1
HTTP1.1支持的請(qǐng)求方法有7種:GET、POST男翰、HEAD另患、OPTIONS氏捞、PUT彤侍、DELETE和TARCE舒帮。在Internet應(yīng)用中彻磁,最常用的方法是GET和POST谒养,這里稍后簡(jiǎn)單介紹下:GET熟妓、POST和HEAD方法刁愿。
URL完整地指定了要訪問的網(wǎng)絡(luò)資源嘹害,通常只要給出相對(duì)于服務(wù)器的根目錄的相對(duì)目錄即可顽爹,因此總是以“/”開頭纤泵,最后,協(xié)議版本聲明了通信過程中使用HTTP的版本镜粤。
1)GET
GET方法用于獲取由 Request-URI 所標(biāo)識(shí)的資源的信息夕吻,是默認(rèn)的HTTP請(qǐng)求方法,例如當(dāng)我們通過在瀏覽器的地址欄中直接輸入網(wǎng)址的方式去訪問網(wǎng)頁的時(shí)候繁仁,瀏覽器采用的就是 GET 方法向服務(wù)器獲取資源涉馅。
GET以URL方式提交數(shù)據(jù)(比如參數(shù)和表單數(shù)據(jù)),只經(jīng)過了簡(jiǎn)單的編碼就它將作為URL的一部分向服務(wù)器發(fā)送請(qǐng)求黄虱,例如:http://localhost/login.php?username=aa&password=1234稚矿, 因此在安全性和url長(zhǎng)度上都會(huì)有所限制。
(2)POST
POST方法請(qǐng)求服務(wù)器接收在請(qǐng)求中封裝的實(shí)體捻浦,并將其作為由 Request-Line 中的 Request-URI 所標(biāo)識(shí)的資源的一部分晤揣,即POST方法將數(shù)據(jù)封裝在消息主體(entity-body),相對(duì)于GET方法而言朱灿,可接受大批量數(shù)據(jù)且消息體中的數(shù)據(jù)并無編碼要求昧识。
就解釋腳本而言,GET方法的數(shù)據(jù)會(huì)存放在QUERY_STRING環(huán)境變量中盗扒,可使用$_GET獲取跪楞,而POST方法提交的數(shù)據(jù)則可以從標(biāo)準(zhǔn)輸入流中獲取,可使用$_POST獲取侣灶。
(3)HEAD
HEAD 方法與 GET 方法幾乎是相同的甸祭,它們的區(qū)別在于 HEAD 方法請(qǐng)求的話,服務(wù)器返回的只是響應(yīng)標(biāo)題褥影,而不是完整的內(nèi)容池户。對(duì)于 HEAD 請(qǐng)求的回應(yīng)部分來說,它的 HTTP 頭部中包含的信息與通過 GET 請(qǐng)求所得到的信息是相同的;通常被用于測(cè)試超鏈接的有效性校焦,是否可以訪問赊抖,以及最近是否更新。
消息頭(Message Headers)
由域名/值對(duì)組成寨典,每行一對(duì)熏迹,域名和值之間用緊跟的英文冒號(hào)(“:”),單空格(SP)分開凝赛。消息頭通知服務(wù)器關(guān)于客戶端的功能和標(biāo)識(shí)注暗,如 Host: www.baidu.com 。在 HTTP/1.1 協(xié)議中墓猎,Host 消息頭是必選的捆昏。還可以有其他一些如 Accept-Charset、Accept-Encoding毙沾、Authorization 骗卜、Set-Cookie等等,詳見 RFC1945左胞,RFC2616寇仓。
消息體(Entity Body)
HTTP 消息的消息體(如果存在),用于攜帶與請(qǐng)求相關(guān)聯(lián)的數(shù)據(jù)烤宙,例如可以存一些請(qǐng)求需要的參數(shù)等遍烦。由消息頭中的 Content-Length 或 Transfer-Encoding 來指示,比如 Content-Type 說明了數(shù)據(jù)的傳輸類型躺枕,Content-Length說明了請(qǐng)求主體的字節(jié)數(shù)服猪。
一個(gè)完整的帶消息體的 HTTP 請(qǐng)求示例如下:
POST /news.asp HTTP/1.1
Host: demo.com:80
Content-Length: 15
<空行,通知服務(wù)器以下不再有請(qǐng)求頭>
[a=1,(b=2,c=3)]
Rollback 斷點(diǎn)2
了解了HTTP請(qǐng)求的數(shù)據(jù)格式后拐云,我們?cè)俅螘由衔摹?/p>
應(yīng)用層的 http 請(qǐng)求準(zhǔn)備好后罢猪,瀏覽器在傳輸層發(fā)起一條到達(dá)服務(wù)器的 tcp 連接,這個(gè)時(shí)候應(yīng)該開始三次握手的過程(考究網(wǎng)絡(luò)傳輸?shù)膱?bào)文發(fā)送細(xì)節(jié)叉瘩,比如三次握手膳帕,路由轉(zhuǎn)發(fā),擁塞避免等等)薇缅,tcp 包被封裝到網(wǎng)絡(luò)層的 ip 包里面危彩,ip 包再被封裝到數(shù)據(jù)鏈路層的數(shù)據(jù)幀結(jié)構(gòu)中,再通過物理層的比特流送出去捅暴,這些分層的意義在于分工合作恬砂,數(shù)據(jù)鏈路層通過 CSMA/CD 協(xié)議保證了相鄰兩臺(tái)主機(jī)之間的數(shù)據(jù)報(bào)文傳遞咧纠,而網(wǎng)絡(luò)層的 ip 數(shù)據(jù)包通過不同子網(wǎng)之間的路由器的路由算法和路由轉(zhuǎn)發(fā)蓬痒,保證了互聯(lián)網(wǎng)上兩臺(tái)遙遠(yuǎn)主機(jī)之間的點(diǎn)對(duì)點(diǎn)的通訊,不過這種傳輸是不可靠漆羔,于是可靠性就由傳輸層的 tcp 協(xié)議來保證梧奢,tcp 通過慢開始狱掂,乘法減小等手段來進(jìn)行流量控制和擁塞避免,同時(shí)提供了兩臺(tái)遙遠(yuǎn)主機(jī)上進(jìn)程到進(jìn)程的通信亲轨,最終保證了 http 的請(qǐng)求頭能夠被遠(yuǎn)方的服務(wù)器上正在監(jiān)聽的 http 服務(wù)器進(jìn)程收到趋惨,終于,數(shù)據(jù)包在跳與跳之間被拆了又封裝惦蚊,在子網(wǎng)與子網(wǎng)之間被轉(zhuǎn)發(fā)了又轉(zhuǎn)發(fā)器虾,最后進(jìn)入了服務(wù)器的操作系統(tǒng)的緩沖區(qū),服務(wù)器的操作系統(tǒng)由此給正在被阻塞住的 accept 函數(shù)一個(gè)返回蹦锋,將他喚醒兆沙。。莉掂。好葛圃,暫停存檔。雖然不甚明了憎妙,但印象中一個(gè)服務(wù)器可配置多個(gè)站點(diǎn)域名库正,即一個(gè)IP綁定多個(gè)域名,比如租用的虛擬主機(jī)厘唾;而當(dāng)為了負(fù)載均衡褥符,一個(gè)域名是可對(duì)應(yīng)到多個(gè)IP地址,這種多對(duì)多的映射關(guān)系是不是有點(diǎn)暈??抚垃,是不是有點(diǎn)好奇服務(wù)器怎么調(diào)取執(zhí)行的属瓣?既然是考究過程,我們也大致了解一下讯柔,不感冒的可自行跳過抡蛙。
斷點(diǎn)3: 服務(wù)器域名、IP以及站點(diǎn)間的關(guān)系
在IIS中,每個(gè) Web 站點(diǎn)都由IP地址魂迄、主機(jī)頭(HOST)和端口三部分組成且唯一標(biāo)識(shí)(考究NGINX下的多站點(diǎn)配置)粗截。
對(duì)于一些小規(guī)模的網(wǎng)站,為了減少系統(tǒng)的運(yùn)行成本和管理難度捣炬,經(jīng)常會(huì)與其他網(wǎng)站共享一臺(tái)物理機(jī)器熊昌。這種虛擬主機(jī)有兩種工作方式:1. 基于IP地址的虛擬主機(jī)方式:物理機(jī)器上同時(shí)設(shè)置有多個(gè)IP地址,不同的主機(jī)名host解析到不同的IP地址湿酸,進(jìn)而判定哪個(gè)虛擬主機(jī)提供服務(wù)婿屹。這種方式需要在虛擬主機(jī)服務(wù)器上設(shè)立多個(gè)IP地址,既浪費(fèi)IP又限制了一臺(tái)機(jī)器所能容納的虛擬主機(jī)數(shù)目推溃。但是昂利,這種方式卻是早期使用的HTTP?1.0協(xié)議唯一支持的虛擬主機(jī)方式;?2. 基于主機(jī)名的虛擬主機(jī)方式:根據(jù)斷點(diǎn)2對(duì)HTTP請(qǐng)求格式的解析,我們知道HTTP/1.1 協(xié)議中蜂奸,Host 消息頭是必選的犁苏。服務(wù)器http服務(wù)進(jìn)程接收到HTTP請(qǐng)求后,會(huì)根據(jù)“Host:”語句判定客戶程序請(qǐng)求是要由哪個(gè)虛擬主機(jī)的提供服務(wù)扩所,這也是目前很常見的一種形式围详。
如果服務(wù)器端使用的http服務(wù)進(jìn)程是Apache,那么在Apache的配置文件中加入VirtualHost即可新增虛擬主機(jī)祖屏,如下圖示:
大體了解了一個(gè)IP綁定多個(gè)域名的運(yùn)行方式后助赞,我們來了解下一個(gè)域名對(duì)應(yīng)到多個(gè)IP,比較典型的應(yīng)該是“一個(gè)域名對(duì)應(yīng)多個(gè)IP地址的負(fù)載均衡的實(shí)現(xiàn)”袁勺,也叫“DNS負(fù)載均衡技術(shù)”嫉拐,詳情可參見http://www.cnblogs.com/cuihongyu3503319/archive/2012/07/09/2583129.html。
DNS負(fù)載均衡技術(shù)(dns輪詢魁兼,或者自己做解析)是在DNS服務(wù)器中為同一個(gè)主機(jī)名配置多個(gè)IP地址婉徘,在應(yīng)答DNS查詢時(shí),DNS服務(wù)器對(duì)每個(gè)查詢將以DNS文件中主機(jī)記錄的IP地址按順序返回不同的解析結(jié)果(隨機(jī)性)咐汞,將客戶端的訪問引導(dǎo)到不同的機(jī)器上去盖呼,使得不同的客戶端訪問不同的服務(wù)器,從而達(dá)到負(fù)載均衡的目的化撕。
為了使本DNS服務(wù)器和其他DNS服務(wù)器及時(shí)交互几晤,保證DNS數(shù)據(jù)及時(shí)更新,使地址能隨機(jī)分配植阴,一般都要將DNS的刷新時(shí)間設(shè)置的較小蟹瘾,但太小將會(huì)使DNS流量大增造成額外的網(wǎng)絡(luò)問題。
由于戰(zhàn)線不易拉的過長(zhǎng)掠手,關(guān)于負(fù)載均衡的其他相關(guān)方法有時(shí)間再贅述吧憾朴。
個(gè)人思考:其原理倒是淺顯易懂,正如上面所說喷鸽,這種DNS負(fù)載均衡技術(shù)众雷,是在應(yīng)答DNS查詢時(shí)將客戶端請(qǐng)求引導(dǎo)的不同的機(jī)器上(地址要隨機(jī)分配)以達(dá)到負(fù)載均衡,那么:1. 根據(jù)文章最開始提到的“客戶端域名的解析過程”做祝,要想走到DNS查詢砾省,瀏覽器緩存的TTL要夠合理吧(這或許是要將DNS刷新時(shí)間設(shè)置較小的原因?)混槐,host要沒配置過吧~~~编兄。。声登。 2. 這種簡(jiǎn)單的輪詢負(fù)載算法狠鸳,不同的服務(wù)器的性能差異及當(dāng)前服務(wù)器的運(yùn)行狀態(tài)揣苏,如何有效的做到隨機(jī)分配,DNS響應(yīng)均衡也是個(gè)難點(diǎn)吧碰煌?