1 源頭---網(wǎng)址
從上圖可知,URL 中可以包含服務器的域名,,文件的路徑,,收件人郵件地址,用戶名,,密碼等信息,。總之URL想表達的是:
從上面的結果我們可以得出,,Web 服務器名稱為 www. ,文件路徑名為 /dir1/index.html,。所以這個URL表示我要訪問www.這個web服務器上路徑為/dir/index.html的文件,。 下面我們對這個URL稍微改動: (a)http://www./dir/
(c)http://www.
(d)http://www./whatisthis
2 HTTP初探
首先HTTP協(xié)議定義了客戶端和服務器之間交互的消息內(nèi)容和步驟,。簡單的說呢即請求的信息包括了'請求啥'以及'你要進行什么操作',和我們面試的時候一樣,,簡歷上面寫了XX項目,,我們是不是也需要清楚自己的項目是什么,你在項目中什么角色一樣且做了哪些部分,,別寫上去的東西一問三不知就比較尷尬了 在HTTP中請求啥這部分叫做 'URI',,URI主要存放網(wǎng)頁數(shù)據(jù)的文件名或者是CGI程序如'/Manage/index.html'等,。 “進行啥操作”統(tǒng)稱為方法。希望服務器能完成什么工作,,比如讀取URI中表示的數(shù)據(jù),。哪都有哪些方法可以使用呢,這張圖總結常用的幾種方法以及含義 這里提一下比較常用且面試常問的兩個方法
當訪問 Web 服務器獲取網(wǎng)頁數(shù)據(jù)的時候,,使用的幾乎都是 Get 方法,。在請求消息中表明使用Get方法,然后在URI 中表明文件名,,比如是 /manage/index.html,。服務器收到消息后,會打開/manage/index.html并讀取里面的數(shù)據(jù),,然后存放于相應消息中并返回給客戶端,,最后在屏幕中完成呈現(xiàn)。
當我們在購物填寫地址信息,,或者填寫問卷信息的時候,,將內(nèi)容填寫到表格中,然后點擊提交這個過程,,實際上通常就是采用的POST方式,。這樣看來,采用POST的方式提交數(shù)據(jù),,我們需要準備三樣東西,,分別為:所提供的方法,URL 和服務端,。服務器收到請求數(shù)據(jù)后發(fā)送給 URI 所指定的應用程序,,然后服務端獲取應用程序的執(zhí)行結果并在響應信息中返回給客戶端。 OK,,現(xiàn)在我們目標基本上明確了,,將各個需要發(fā)送的內(nèi)容組合并發(fā)給服務器。服務器進行解析,,根據(jù)客戶端的需求完成使命后將需要反饋的信息存放在響應消息中,,那么對于客戶端而言,也不知道到底是不是想要的結果,。所以,,服務端會在響應頭中用一個狀態(tài)碼表示操作的結果是成功還是失敗,比如 200 表示成功,,404可能為沒找到文件,。 此時客戶端收到了服務端的響應信息,瀏覽器覺得這太 lowb 了,,給你渲染下并完美的呈現(xiàn)在我們眼前,。HTTP的使命就此完成,。 3 HTTP請求頭---保命天子
先寫方法,,加上空格,然后寫上 URI(文件或者程序的路徑名),,行末尾協(xié)商HTTP版本號即完成第一行的任務,。 第二行為消息頭。這一行主要是對第一行內(nèi)容的進一步補充,。比如會告知客戶端支持的數(shù)據(jù)類型,、壓縮格式,數(shù)據(jù)有效期等,,具體的我放張圖,,需要的可以去了解下。 第三行為空行,,然后加上需要發(fā)送的數(shù)據(jù),,這為消息體。整個消息也就結束 4 HTTP響應---我行我素
響應信息返回后顯示在屏幕中,,如果為純文字,到此就結束了,。但是大部分時候都會有圖片,,視頻,音頻等信息,,這個時候怎么辦,? 瀏覽器會從響應信息中的文字搜索相應的標簽,如果有圖片等其他信息,,則再次請求服務器,,按照相應的文件名向服務器發(fā)送請求并顯示在剛才預留的空間中。至此,,我們訪問網(wǎng)頁的初級過程版本就差不多結束了,。下面用一個案例加深下印象。 上圖是簡化版,,在這里再穩(wěn)固幾點
5 刨根
DNS 有些小伙伴說 Mac 地址不能作為標識嗎?可是太不容易記憶了,,從而出現(xiàn)了簡化了 IP 形式,,可以它被直接暴露給外網(wǎng)不說,還讓人類覺得比較麻煩,,干脆用幾個字母算了,,也就是域名了。域名不僅僅能夠代替 IP,,還有很多其他的用途比如在 Web 應用中用來標識虛擬主機,。
DNS報文結構 基礎結構部分
重點!?。,。』A結構中的標志字段細分如下: 標志字段
問題部分 該部分是用來顯示DNS查詢請求的問題,其中包含正在進行的查詢信息,,包含查詢名(被查詢主機名字),、查詢類型、查詢類,。
資源記錄部分
資源記錄部分
DNS解析詳解
DNS核心系統(tǒng) 根域名服務器(Root DNS Server),大哥,,管理頂級域名服務并放回頂級域名服務器IP,,比如'com','cn' 頂級域名服務器(Top-level DNS Server),每個頂級域名服務器管理各自下屬,比如com可以返回baidu.com域名服務器的IP 權威域名服務器(Authoritative DNS Server),管理當前域名下的IP地址,,比如Tencent.com可以返回www.tencent.com的 IP 地址 核心系統(tǒng) 舉個例子,,假設我們訪問'www.google.com'
嘿嘿,目前全世界13組根域名服務器還有上百太鏡像,,但是為了讓它能力更強,,處理任務效率更高,盡量減少域名解析的壓力,,通常會加一層'緩存',,意思是如果訪問過了,就緩存,,下一次再訪問就直接取出,,也就是咱么經(jīng)常配置的'8.8.8.8'等 操作系統(tǒng)中同樣也對DNS解析做緩存,比如說曾訪問過'www.google.com',, 其次,,還有我們熟知的hosts文件,當在操作系統(tǒng)中沒有命中則會在hosts中尋找,。 這樣依賴,,相當于有了 DNS 服務器,操作系統(tǒng)的緩存和 hosts 文件,,能就近(緩存)完成解析就好,不用每次都跑到很遠的地方去解析,,這樣大大減輕的 DNS 服務器的壓力,。畫了一個圖,加深印象 DNS解析過程 嗯?想必應該知道這個過程了,,我們再舉個例子,,假設我們訪問www.qq.com
Socket庫 實際上,,這是一段程序包含在操作系統(tǒng)的 Socket 庫中,,我們只需要調(diào)用相關的庫就可以獲得IP。那 Socket 庫又是個什么東西,? 庫,,文庫, Github 倉庫,,總之一定是 xxx 的集合,。為了簡便開發(fā),大佬們會將很多方法封裝為庫,開發(fā)人員直接調(diào)用即可,,這樣不僅節(jié)省編程的工作量,,也提高開發(fā)的工作效率,但是如果庫出了問題,,你就可能不是 GG 半會兒了,。Socket 亦是如此,提供了一些網(wǎng)絡編程相關的庫,,方便開發(fā)人員調(diào)用操作系統(tǒng)的網(wǎng)絡功能,。如下圖,當我們調(diào)用 gethostbyname 的時候,,就會向 DNS 服務器發(fā)送查詢消息,,然后 DNS 服務器進行響應。響應的信息就會包含查詢到的IP地址,,解析器取出IP地址并寫入指定的內(nèi)存中,,瀏覽器只需要從內(nèi)存地址中取出 IP 地址然后加上HTTP請求信息交給操作系統(tǒng)大哥即可 現(xiàn)在我們拿到了 IP 地址,就可以委托協(xié)議棧向這個目標 IP 發(fā)送信息了,,下面我看看使用Socket庫發(fā)送數(shù)據(jù)的過程 理解下上圖,,服務端創(chuàng)建套接字,我們可以想象為一個水管,,當服務端監(jiān)聽進入等待狀態(tài)后,,客戶端就可以連接服務端并塞數(shù)據(jù)到管子中,進行數(shù)據(jù)的收發(fā),。當然,,如果不想聊天了,任何一方都可以斷開,,套接字隨機也就斷開,,通信結束??偨Y為這幾個階段
創(chuàng)建套接字,調(diào)用socket函數(shù)會返回一個描述符,,這個描述符類似于門牌號,,通過門牌號就可知道你住在那一房間。隨后的通信直接關聯(lián)此描述符即可 連接 創(chuàng)建完套接字,,我們就得開始建立連接了,,可是還是需要協(xié)議棧的幫忙,那么協(xié)議棧都干了啥呢,? 我們從上到下來刮一遍
將剛才我們創(chuàng)建的客戶端套接字與服務器那邊的套接字連接上。使用的函數(shù)為connect,,其中需要三個參數(shù):
通信 一旦套接字建立連接,隨著就可以委托協(xié)議棧完成數(shù)據(jù)的發(fā)送操作,。具體流程
在真正的實體情況下,所謂連接通常是網(wǎng)線的連接,,網(wǎng)線確實一直連接著,,在這里,,連接的意思是通信的雙方能夠交換控制信息,并在套接字中記錄這些信息,。
服務端通過Socket庫中的read接收消息,這里注意,,調(diào)用read的時候需要制定用于存放響應消息的內(nèi)存地址,,也叫做接收緩存區(qū)。
具體操作步驟
6 應用階段
仔細理解這兩點,,你會發(fā)現(xiàn)兩者沖突了,。因為如果考慮長度的優(yōu)先級更高,那么網(wǎng)絡效率高,,但是可能等待緩沖區(qū)的時間比較長,。如果時間優(yōu)先級更高,延遲時間就短,,但是降低了網(wǎng)絡效率,。所以在應用程序中提供了選項,在開發(fā)的過程中可以根據(jù)實際情況進行設置,。
數(shù)據(jù)大了則進行拆分,拆分后為了能完整組裝,,每個小塊提前做好標識,。當判斷需要發(fā)送這些數(shù)據(jù)的時候,就在每一塊的數(shù)據(jù)前面加上TCP頭部,,然后交給IP模塊進行數(shù)據(jù)的發(fā)送 ,。 ACK確認機制
我們客戶端在發(fā)送數(shù)據(jù)的時候,,會告知對方發(fā)送的數(shù)據(jù)從第幾個字節(jié)開始且長度是多少,,對于接收方而言也是能很好地清楚是否完整的接收。比如上次接收到的是520字節(jié),,那么接下來收到的包是521,,說明中間沒什么問題。如果收到的包是1314,,中間這段時間可能就出軌了,。這樣子,如果沒有遺漏,,接收方就會將一共接收到了多少字節(jié)寫到ACK中并發(fā)送給對方,。不知道大家理解沒有,我再換個方式說一遍,。發(fā)送電報:“我現(xiàn)在發(fā)送的數(shù)據(jù)是從XX字節(jié)開始的部分,,一共有XX字節(jié)哈”,接收端:“到XX字節(jié)之前的數(shù)據(jù)我都接收完了',,這就是確認機制,。在此跑一個面試題,為什么序號不是從'1'開始,? TCP正是采用這樣的確認機制,,數(shù)據(jù)在傳輸過程中,在諸如網(wǎng)絡集線器等設備就不在有錯誤補償機制,,這些設備檢測到錯誤就直接丟棄相應的包,。TCP采用ACK的確認機制,這個確認的回復時間是根據(jù)什么來定,?是固定時間內(nèi)必須返回ACK呢,,還是會根據(jù)距離遠近等動態(tài)調(diào)整呢? 通常來說,,在局域網(wǎng)中ACK的返回相對會比互聯(lián)網(wǎng)返回所需時間更短,。TCP采用動態(tài)調(diào)整等待時間的方法。這里所說的等待時間是根據(jù)ACK返回所需時間來判斷的,。也就是說TCP在發(fā)送數(shù)據(jù)后就會持續(xù)觀測ACK返回時間,,如果發(fā)現(xiàn)慢了則會延長等待的時間。 我們每發(fā)一個包,,等待確認后再發(fā)送另一個包,。那么在等待的這個過程是不是就浪費了時間呢。為了改變這樣的情況,,TCP采用了滑動窗口的方式管理數(shù)據(jù)發(fā)送和ACK號的操作,。 滑動窗口
首先,,TCP接收方收到包以后,,并不是馬上處理交給應用程序,,而是先存在暫存區(qū),,但是發(fā)送方實在是太快了,,接收方處理不過來,暫存區(qū)也滿了,。怎么解決,?我們希望發(fā)送方能夠隨時知道接收方的接收數(shù)據(jù)能力,這樣就不會無腦的扔數(shù)據(jù)過去了,。ok,TCP 就是這樣處理的,,它會告訴發(fā)送方自己最多還能處理多少數(shù)據(jù),,然后發(fā)送方就會根據(jù)接收方的大小進行數(shù)據(jù)發(fā)送控制,這也就是滑動窗口的精髓所在,。 通過這樣長途跋涉終于發(fā)送了HTTP請求信息,,等待著響應信息,客戶端通過read獲取響應信息,,和發(fā)送數(shù)據(jù)時協(xié)議棧工作類似,,從接收緩沖區(qū)中取出數(shù)據(jù)并傳遞給應用程序 斷開連接 在 Web 使用的HTTP協(xié)議規(guī)定,如果web服務器發(fā)送完消息后,,就應該主動的斷開操作,。客戶端知道斷開后,,就當再執(zhí)行read調(diào)用時就會被提醒收發(fā)數(shù)據(jù)已結束,,隨即也調(diào)用 close 進行斷開操作。前面我們說過,,每獲取一次數(shù)據(jù)就會執(zhí)行一次連接,,這樣的效率是非常低的,所以在 HTTP1.1 中就可以一次連接多次請求和響應,?!?/p> 假設服務器端調(diào)用close程序,此時協(xié)議棧會生成斷開信息的TCP頭部,,也就是將控制位中的FIN置為1,,然后委托給IP模塊向客戶端發(fā)送數(shù)據(jù) 客戶端收到服務端的 Fin 為1的包后,,為了告知服務端已經(jīng)收到了這個 Fin 包,會返回一個ACK號,,等待應用程序來處理數(shù)據(jù),。當應用程序調(diào)用read的時候,發(fā)現(xiàn)服務端告訴它的是數(shù)據(jù)已經(jīng)全部收到,,所以客戶端隨即開始關閉操作,,生成FIN比特為1的TCP包,然后交給IP模塊發(fā)送給服務器,,然后服務端段返回 ACK 表示收到,。這樣客戶端與服務端全部關閉結束。 7 IP上面講述了想要實現(xiàn)通信,,在TCP連接揮手時需要請IP模塊幫忙并封裝為包發(fā)送給就近的網(wǎng)絡設備,,網(wǎng)絡設備根據(jù)頭部控制信息確定目的地址,如何確定的呢,?轉發(fā)設備中有一張映射表,,其中表中能表示'你可以將包發(fā)送到XX目的地',此時IP協(xié)議再委托以太網(wǎng)協(xié)議,,尋找路由器的以太網(wǎng)地址(mac地址),,如果有多個轉發(fā)設備,原理過程一樣,,最終到達接收方的網(wǎng)絡設備,。 整個流程算是了解了,我們繼續(xù)深究下IP模板到底是如何完成收發(fā)操作的,。當TCP委托IP模塊進行數(shù)據(jù)包傳送的時候,,告訴了目的地址是在哪里,然后經(jīng)過一系列的中間網(wǎng)絡設備尋找以太網(wǎng)地址也就是mac地址,,所以現(xiàn)在擁有了IP頭部和mac頭部,,發(fā)送給網(wǎng)卡等硬件設備,網(wǎng)卡將數(shù)字信息轉換為電信號或光信號并發(fā)送出去,。 當接收方收到數(shù)據(jù)包會做出響應,,其路線相反。數(shù)據(jù)包以電信號的方式從網(wǎng)線發(fā)出,,傳遞給IP模塊,,IP模塊將MAC頭部、IP頭部后面數(shù)據(jù)傳遞給TCP模塊 IP地址通過TCP模塊獲取目的地址,,而TCP模塊是從應用程序中獲取IP地址,,對于IP模塊而言,只是乖乖的將包發(fā)往應用程序指定的接收方,那假設這個IP地址是錯誤的怎么辦呢,,IP模塊不管,,他只是負責打個包發(fā)出去,因為這個事兒是應用程序的任務?,F(xiàn)在我們已經(jīng)知道IP模塊中有填寫目的IP地址,,還有哪些重要的控制信息呢 從上圖我們發(fā)現(xiàn)還需要32字節(jié)的發(fā)送方IP地址,如果當前計算機只有一張網(wǎng)卡,,那就是計算機的IP地址,。
MAC 生成了IP頭部后,需要在IP頭部加上MAC頭部,,其中包含了接收方和發(fā)送方的MAC地址信息,,因為在以太網(wǎng)的世界里需要按照以太網(wǎng)的規(guī)則辦事兒
此時IP模塊完成所有任務,。下面就到網(wǎng)卡 8 網(wǎng)卡上面辛辛苦苦的將包組裝完成,但都是數(shù)字信息,,我們需要轉換為電信號或者光信號才能在網(wǎng)絡上傳輸,,這就網(wǎng)卡的作用。但是就當當?shù)囊粔K網(wǎng)卡能干啥,,啥也干不了,,他需要插上去并裝上網(wǎng)卡驅(qū)動,計算機開機啟動之時對網(wǎng)卡進行初始化才能開始使用,。 網(wǎng)卡驅(qū)動從IP模塊獲取包之后,,復制到網(wǎng)卡緩沖區(qū),然后告知MAC層,MAC模塊從緩沖區(qū)取出包并加上頭部和起始幀,,末尾加上幀校驗序列 發(fā)送信號分為兩種方式,,一種是集線器方式,一種是交換機的全雙工模式,。 集線器方式 發(fā)送信號之前需要先檢查線路中是否存在其他信號,,以免造成沖突。MAC模塊從頭部開始逐比特轉換為電信號,,然后交給 PHY 模塊發(fā)送出去,,PHY模塊將信號轉換為可以在網(wǎng)線上傳輸?shù)母袷讲⑼ㄟ^網(wǎng)線發(fā)送出去。但是我們知道,,由于電磁波接觸到金屬等半導體后會產(chǎn)生電流,,與信號摻雜在一起,這樣勢必就會對原有的信號造成影響,,為了盡量的避免這種影響,,使用了雙絞線的方式來抑制噪聲。為什么雙絞線就可以抑制噪聲嘞,,因為當電磁波接觸到信號線時,,假設電流方向為右,當使用雙絞線的方式螺旋纏繞后,,兩個信號線所產(chǎn)生的的電流方向就會相反,,從而相當于負負得正低效,不的不說闊學家們牛掰 全雙工模式 全雙工模式可以讓發(fā)送和接收操作同時進行且不產(chǎn)生碰撞,,因為在全雙工模式下,,無需等待其他信號就可發(fā)送信號,所以比半雙工更快 接收方 在半雙工的通信過程中,,發(fā)送信號到達結合搜模塊,,信號的開頭是報頭,從起始幀分隔符開始將后面的信號轉換為數(shù)字信息,,即 PHY模塊 先開始工作,,將信號轉換為通用格式并交付給MAC模塊,MAC模塊從頭開始將信號轉換為數(shù)字信號并存放緩沖區(qū),,這里注意,,到達信號末尾的時候需要檢查FCS,檢查方法是通過響應算法計算出結果并和包末尾比較,,如果不一致則會當做錯誤包丟棄,。FCS沒問題,再通過MAC頭部接收方的地址查看是否給自己的包,,如果不是也就沒必要亂收,,直接丟棄,,如果MAC地址一致則將包存放緩沖區(qū),此時MAC模塊完成任務,。 我們知道計算機會執(zhí)行千萬種任務,,它不會隨時監(jiān)控網(wǎng)卡的行蹤,所以需要打斷計算機當前執(zhí)行的任務,,告訴它網(wǎng)卡現(xiàn)在發(fā)生的事情,,這就是中斷。網(wǎng)卡驅(qū)動被中斷處理程序調(diào)用后,,會從網(wǎng)卡的緩沖區(qū)中取出收到的包,,并通過 MAC 頭部中的以太類型字段判斷協(xié)議的類型,如果是0080則代表IP協(xié)議,,那么網(wǎng)卡驅(qū)動就講這樣包給TCP/IP協(xié)議棧,。此時IP模塊開始工作
此時IP模塊交給TCP模塊,TCP模塊根據(jù)IP頭部的接收方和發(fā)送方IP地址,,以及TCP頭部的的發(fā)送,,接收端口信息,組成<發(fā)送地址,,接收地址,,源端口,目的端口>四元組信息查找對應的套接字,,從而可查看通信的狀態(tài)并執(zhí)行相關的通信,。 9 防火墻
不知道大家用過Tcpdump、Wireshark等工具沒,,它的過濾機制類似于防火墻的原理,,那么為了實現(xiàn)過濾,我們就需要深刻了解各層協(xié)議的頭部構造,,只有熟悉其頭部字段,,才能在過濾表達式中施展魔法。 通過IP 端口等過濾
設置控制位的方式
隨著系統(tǒng)越來與牛逼,收益越來越來,,老板跑來:“小伙計,,用戶反映請求后半天收不到消息誒”。豈不是廢話么,,系統(tǒng)做得好,,跑路少不了,錢不到手,,怎敢跑路,,成,一頓性能測試猛如虎,,哎呀,,加個負載均衡試試? 負載均衡
從曾經(jīng)的一臺服務器,,增加到現(xiàn)在到五臺服務器,相當于每臺服務器分擔1/5,,這樣壓力自然小了很多,,那問題來了,怎么才能將請求分散到各臺服務器呢,?哪都有哪些負載均衡的方案,? 砸錢
HTTP重定向負載均衡 也屬于比較直接,當HTTP請求到達負載均衡服務器后,,使用一套負載均衡算法計算到后端服務器的地址,,然后將新的地址給用戶瀏覽器,,瀏覽器收到重定向響應后發(fā)送請求到新的應用服務器從而實現(xiàn)負載均衡,如下圖所示 優(yōu)點:
缺點:
DNS負載均衡
反向代理負載均衡
IP負載均衡
注意,這種方案通常屬于內(nèi)核級別,,如果數(shù)據(jù)比較小還好,,但是大部分情況是圖片等資源文件,這樣負載均衡服務器會出現(xiàn)響應或者請求過大所帶來的瓶頸 數(shù)據(jù)鏈路負載均衡
以上介紹了幾種負載均衡的方式,,但是很重要的負載均衡算法卻沒有設計,其中包含了輪詢,,隨機,,最少連接,下面分別對此進行介紹(假設以Nginx為例) 輪詢
upstream XXX{ Hash方式*處理公式:abs(客戶端ip.hash())%服務器數(shù)量*
出現(xiàn)的問題
最小連接方式
upstream XXX{
基于權重的方式
此時通過weight權重進行資源的分配。down表示當前服務器不參加負載均衡,。 |
|