久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

40張圖大揭秘:輸入網(wǎng)址后到底發(fā)生了什么

 清風劍舞 2020-08-21

計算機網(wǎng)絡的重要程度不言而言,也是非常的復雜,。今天我將從輸入URL這個簡單例子開始,,一起探索數(shù)據(jù)包的心路歷程。先看文章的大綱,。

大綱

1 源頭---網(wǎng)址

網(wǎng)址即平時所說的URL,。就是經(jīng)常使用的以“Http://”開頭的那一串東東,其實常用的還有很多,,比如 'FTP' , 'FILE'等,,我們所訪問的目標網(wǎng)站不同,網(wǎng)址開頭的寫法也就不同,,下面列出常見的幾種URL,。

URL基本格式

從上圖可知,URL 中可以包含服務器的域名,,文件的路徑,,收件人郵件地址,用戶名,,密碼等信息,。總之URL想表達的是:

  • 訪問時所使用的協(xié)議,。'HTTP' , 'FTP' , 'FILE'等

  • 用戶名/密碼可選

  • 所需訪問或下載文件的路徑

URL的相貌我們已經(jīng)銘記于心,,而且對于 URL 各個子模塊也有了基本的認識,,可別小看這幾個小模塊,慢工出細活,。我們拆分后仔細看看

  • URL拆分

  • 理解URL個元素的含義

URL的拆分

從上面的結果我們可以得出,,Web 服務器名稱為 www. ,文件路徑名為 /dir1/index.html,。所以這個URL表示我要訪問www.這個web服務器上路徑為/dir/index.html的文件,。

下面我們對這個URL稍微改動:

(a)http://www./dir/

這里注意,dir 后面的文件名被省略了,,這樣的話服務器會使用默認的文件名,,就反復咱們定義變量的時候,如果沒有賦初值,,通常會給默認值,。同樣的道理,服務器也會給一個默認的文件名,,不同的服務器默認的文件會不一樣,通常會是 Index.html,。

(c)http://www.

這個就比較狠了,,后面的'/'直接沒有,那該訪問啥呢,?如果沒有路徑名,,則代表訪問根目錄下面設置的默認文件。

(d)http://www./whatisthis

這末尾的 whatisthis 是什么呢,?在這種情況,,如果服務器中存在 whatisthis 的文件,則按照文件處理,。如果是 wahtsthis 為目錄,,則按照目錄進行處理。

2 HTTP初探

通過第一步對URL的解析,,知道了我們所訪問的目標是什么,,接下來是不是就要請求數(shù)據(jù)了呢?在做請求之前,,我們一起回憶一下HTTP的基礎知識

在這里插入圖片描述

首先HTTP協(xié)議定義了客戶端和服務器之間交互的消息內(nèi)容和步驟,。簡單的說呢即請求的信息包括了'請求啥'以及'你要進行什么操作',和我們面試的時候一樣,,簡歷上面寫了XX項目,,我們是不是也需要清楚自己的項目是什么,你在項目中什么角色一樣且做了哪些部分,,別寫上去的東西一問三不知就比較尷尬了

在HTTP中請求啥這部分叫做 'URI',,URI主要存放網(wǎng)頁數(shù)據(jù)的文件名或者是CGI程序如'/Manage/index.html'等,。

“進行啥操作”統(tǒng)稱為方法。希望服務器能完成什么工作,,比如讀取URI中表示的數(shù)據(jù),。哪都有哪些方法可以使用呢,這張圖總結常用的幾種方法以及含義

在這里插入圖片描述

這里提一下比較常用且面試常問的兩個方法

  • GET

當訪問 Web 服務器獲取網(wǎng)頁數(shù)據(jù)的時候,,使用的幾乎都是 Get 方法,。在請求消息中表明使用Get方法,然后在URI 中表明文件名,,比如是 /manage/index.html,。服務器收到消息后,會打開/manage/index.html并讀取里面的數(shù)據(jù),,然后存放于相應消息中并返回給客戶端,,最后在屏幕中完成呈現(xiàn)。

  • POST

當我們在購物填寫地址信息,,或者填寫問卷信息的時候,,將內(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請求頭---保命天子

看到這里,我相信大家應該了解了 HTTP 的大概樣貌,。萬事兒都是有原則的,,那么請求的也是有格式的,不聽話就要被打屁屁,。

在這里插入圖片描述

先寫方法,,加上空格,然后寫上 URI(文件或者程序的路徑名),,行末尾協(xié)商HTTP版本號即完成第一行的任務,。

第二行為消息頭。這一行主要是對第一行內(nèi)容的進一步補充,。比如會告知客戶端支持的數(shù)據(jù)類型,、壓縮格式,數(shù)據(jù)有效期等,,具體的我放張圖,,需要的可以去了解下。

在這里插入圖片描述

第三行為空行,,然后加上需要發(fā)送的數(shù)據(jù),,這為消息體。整個消息也就結束

4 HTTP響應---我行我素

響應的內(nèi)容和請求信息的內(nèi)容類似,。只是響應中的第一行內(nèi)容為狀態(tài)碼,表示執(zhí)行結果是否成功,。常見的HTTP狀態(tài)碼如下圖所示

在這里插入圖片描述

響應信息返回后顯示在屏幕中,,如果為純文字,到此就結束了,。但是大部分時候都會有圖片,,視頻,音頻等信息,,這個時候怎么辦,?

瀏覽器會從響應信息中的文字搜索相應的標簽,如果有圖片等其他信息,,則再次請求服務器,,按照相應的文件名向服務器發(fā)送請求并顯示在剛才預留的空間中。至此,,我們訪問網(wǎng)頁的初級過程版本就差不多結束了,。下面用一個案例加深下印象。

在這里插入圖片描述

上圖是簡化版,,在這里再穩(wěn)固幾點

  • Get和Post哪些區(qū)別

  • 請求頭和響應頭哪些位置是需要空格或者空行

  • 常用響應狀態(tài)碼和請求方法

到此,,我們從表面上知道,,從敲入網(wǎng)址,構造請求消息,,收到響應,,并能將美女圖片給呈現(xiàn)在眼前,這樣就完事了,?不好意思,,我們時刻都有一顆的去大廠的心,意味著我們不能只知道表面現(xiàn)象還要適當去了解更多的細節(jié),。

5 刨根

雖然瀏覽器能夠解析我們的網(wǎng)址,,但是它并不具備將消息發(fā)送到網(wǎng)絡中的能力,那是誰打的輔助,?當然是操作系統(tǒng)大哥,,為了讓操作系統(tǒng)大哥幫忙,我們得先拜訪下操作系統(tǒng)大哥,,問問需要我們提供哪些資源,,需要什么,我們就全力配合它,。

  • IP地址

我們在瀏覽器輸入的是網(wǎng)址,,但是操作系統(tǒng)需要的是IP地址,所以我們需要想辦法進行轉換,。轉換的方法就需要請教 DNS 了,。很簡單,我們告訴DNS,,'我的域名是www.,,請告訴我的 IP 地址',OK,,DNS服務器很爽快,,回復'你的IP地址是xxx.xxx.xxx.xxx'。那么問題來了,,我們是如何向 DNS 發(fā)送的這個查詢呢,?我們先來復習DNS

DNS

有些小伙伴說 Mac 地址不能作為標識嗎?可是太不容易記憶了,,從而出現(xiàn)了簡化了 IP 形式,,可以它被直接暴露給外網(wǎng)不說,還讓人類覺得比較麻煩,,干脆用幾個字母算了,,也就是域名了。域名不僅僅能夠代替 IP,,還有很多其他的用途比如在 Web 應用中用來標識虛擬主機,。

在這里插入圖片描述

說了這么多,,協(xié)議頭部,到底有哪些字段,,其含義是什么都還不知道,,那怎么去分析報文,下面我們一起再看看報文什么樣子

在這里插入圖片描述

DNS報文結構

基礎結構部分

DNS報文基礎部分為DNS首部,。其中包含了事務ID,,標志,問題計數(shù),,回答資源計數(shù),,回答計數(shù),權威名稱服務器計數(shù)和附加資源記錄數(shù),。

  • 事務ID:報文標識,,用來區(qū)分 DNS 應答報文是對哪個請求進行響應

  • 標志:DNS 報文中標志字段

  • 問題計數(shù):DNS 查詢請求了多少次

  • 回答資源記錄數(shù):DNS 響應了多少次

  • 權威名稱服務器計數(shù): 權威名稱服務器數(shù)目

  • 附加資源記錄數(shù): 權威名稱服務器對應 IP 地址的數(shù)目

重點!?。,。』A結構中的標志字段細分如下:

在這里插入圖片描述

標志字段

  • QR(Response):查詢請求,,值為0,;響應為1

  • Opcode:操作碼。0表示標準查詢,;1表示反向查詢,;2服務器狀態(tài)請求

  • AA(Authoritative):授權應答,該字段在響應報文中有效,。通過0,1區(qū)分是否為權威服務器,。如果值為 1 時,表示名稱服務器是權威服務器,;值為 0 時,表示不是權威服務器,。

  • TC(Truncated):表示是否被截斷,。當值為1的時候時,說明響應超過了 512字節(jié)并已被截斷,,此時只返回前512個字節(jié),。

  • RD(Recursion Desired):期望遞歸。該字段能在一個查詢中設置,,并在響應中返回,。該標志告訴名稱服務器必須處理這個查詢,這種方式被稱為一個遞歸查詢,。如果該位為 0,,且被請求的名稱服務器沒有一個授權回答,,它將返回一個能解答該查詢的其他名稱服務器列表。這種方式被稱為迭代查詢,。

  • RA(Recursion Available):可用遞歸,。該字段只出現(xiàn)在響應報文中。當值為 1 時,,表示服務器支持遞歸查詢,。

  • Z:保留字段,在所有的請求和應答報文中,,它的值必須為 0,。

  • rcode(Reply code):通過返回只判斷相應的狀態(tài)。

當值為0時,,表示沒有錯誤,;當值為1時,表示報文格式錯誤(Format error),,服務器不能理解請求的報文,;當值為 2 時,表示域名服務器失?。⊿erver failure),,因為服務器的原因?qū)е聸]辦法處理這個請求;當值為 3 時,,表示名字錯誤(Name Error),,只有對授權域名解析服務器有意義,指出解析的域名不存在,;當值為 4 時,,表示查詢類型不支持(Not Implemented),即域名服務器不支持查詢類型,;當值為 5 時,,表示拒絕(Refused),一般是服務器由于設置的策略拒絕給出應答,,如服務器不希望對某些請求者給出應答,。

問題部分

該部分是用來顯示DNS查詢請求的問題,其中包含正在進行的查詢信息,,包含查詢名(被查詢主機名字),、查詢類型、查詢類,。

  • 查詢名:一般為查詢的域名,,也可能是通過IP地址進行反向查詢

  • 查詢類型:查詢請求的資源類型。常見的如果為A類型,表示通過域名獲取IP,。具體如下圖所示

在這里插入圖片描述
  • 查詢類:地址類型,,通常為互聯(lián)網(wǎng)地址為1

資源記錄部分

資源記錄部分包含回答問題區(qū)域,權威名稱服務器區(qū)域字段,、附加信息區(qū)域字段,,格式如下

資源記錄部分

資源記錄部分

  • 域名:所請求的域名

  • 類型:與問題部分查詢類型值一直

  • 類:地址類型,和問題部分查詢類值一樣

  • 生存時間:以秒為單位,,表示資源記錄的生命周期

  • 資源數(shù)據(jù)長度:資源數(shù)據(jù)的長度

  • 資源數(shù)據(jù):按照查詢要求返回的相關資源數(shù)據(jù)

DNS解析詳解

知道了DNS大概是什么,,它的域名結構和報文結構,是時候看看到底怎么解析的以及如何保證域名的解析比較穩(wěn)定和可靠

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'

  • 訪問根域名服務器,這樣我們就會知道'com'頂級域名的地址

  • 訪問'com'頂級域名服務器,,可知道'google.com'域名服務器的地址

  • 最后方位'google.com'域名服務器,,就可知道'www.google.com'的IP地址

嘿嘿,目前全世界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

  • 客戶端發(fā)送一個 DNS 請求,請問 qq 你的IP的什么啊,,同時會在本地域名服務器(一般是網(wǎng)絡服務是臨近機房)打聲招呼

  • 本地收到請求以后,,服務器會有個域名與IP的映射表。如果存在,,則會告訴你,,如果想訪問qq,那么你就訪問XX地址,。不存在則會去問上級(根域服務器):'老鐵,,你能告訴我 www.qq.com'的IP么

  • 根 DNS 收到本地 DNS 請求后,發(fā)現(xiàn)是.com,,'www.qq.com喲,,這個由.com大哥管理,我馬上給你它的頂級域名地址,,你去問問它就好了'

  • 這個時候,,本地 DNS 跑去問頂級域名服務器,'老哥,,能告訴下www.qq.com'的ip地址碼',這些頂級域名負責二級域名比如qq.com

  • 頂級域名回復:'小本本記好,,我給你 www.qq.com 區(qū)域的權威 DNS 服務器地址',它會告訴你

  • 本地DNS問權威DNS服務器:'兄弟,,能不能告訴我 www.qq.com 對應IP是啥'

  • 權威DNS服務器查詢后將響應的IP地址告訴了本地 DNS,,本地服務器將 IP 地址返回給客戶端,從而建立連接,。

那如果我們寫段cs程序都得這么麻煩的,?不不,上面的是大佬們做好,,我們只需要使用相關庫就好了,,這里就得說說Socket庫了。

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)建套接字階段

  • 管子連接到服務端套接字

  • 收發(fā)數(shù)據(jù)

  • 斷開并刪除套接字

那么再具體的實現(xiàn)中是怎樣的呢,?

創(chuàng)建套接字,調(diào)用socket函數(shù)會返回一個描述符,,這個描述符類似于門牌號,,通過門牌號就可知道你住在那一房間。隨后的通信直接關聯(lián)此描述符即可

連接

創(chuàng)建完套接字,,我們就得開始建立連接了,,可是還是需要協(xié)議棧的幫忙,那么協(xié)議棧都干了啥呢,?

在這里插入圖片描述

我們從上到下來刮一遍

  • 最上面是網(wǎng)絡應用程序,,其中包含了瀏覽器,,郵件客戶端等,緊接著是Socket庫,,其中一個功能就是向 DNS服務器發(fā)出請求獲取IP。

  • 往下是操作系統(tǒng)大哥內(nèi)臟,,其中包含了協(xié)議棧,。上面是傳輸層常見的TCP和UDP,分別負責 TCP 協(xié)議的收發(fā)數(shù)據(jù)和 UD P的首發(fā)數(shù)據(jù),。

  • 往下是IP,,控制網(wǎng)絡數(shù)據(jù)包的收發(fā)操作。主要負責將網(wǎng)絡數(shù)據(jù)包發(fā)送給通信對象,。其中包含ICMP,,ARP等協(xié)議。其中ICMP主要負責告知網(wǎng)絡數(shù)據(jù)包在發(fā)送的過程中產(chǎn)生的錯誤信息,,ARP負責根據(jù)IP地質(zhì)查詢MAC地質(zhì)

  • 再往下就是網(wǎng)卡驅(qū)動負責的硬件網(wǎng)卡了,。直白點說是對網(wǎng)線的信號執(zhí)行發(fā)送接收操作

將剛才我們創(chuàng)建的客戶端套接字與服務器那邊的套接字連接上。使用的函數(shù)為connect,,其中需要三個參數(shù):

  • 描述符

connnet會將描述符告訴協(xié)議棧,,協(xié)議棧知道描述符后就來判斷到底使用哪個套接字去連接服務端

  • 地址

這個IP地址即使剛才我們通過DNS獲取的IP地址,并將IP地址告知協(xié)議棧

  • 端口

IP地址是用來區(qū)分網(wǎng)絡中各個計算機而分配的數(shù)值,??梢岳斫鉃楣簿值墓秒娫挘覀兇螂娫掃^去找某人還需要知道名字吧,,不然打過去找誰,?這個某某人就類似端口號,根據(jù)這個端口號我們能找到具體的聯(lián)系人,。所以通過IP+端口的方式確定具體的套接字,。端口號那么多,到底指定多少端口,?不慌,,其實服務器上面使用的大部分端口都事先定義好了,比如HTTP多為80,,SMPT通常為35端口,。這樣子就可以正兒八經(jīng)的通信了

通信

一旦套接字建立連接,隨著就可以委托協(xié)議棧完成數(shù)據(jù)的發(fā)送操作,。具體流程

  • 應用程序準備好需要發(fā)送的數(shù)據(jù)

  • 構造HTTP請求信息

  • 調(diào)用write委托協(xié)議棧發(fā)送數(shù)據(jù)

那連接的真正含義是什么,?

在真正的實體情況下,所謂連接通常是網(wǎng)線的連接,,網(wǎng)線確實一直連接著,,在這里,,連接的意思是通信的雙方能夠交換控制信息,并在套接字中記錄這些信息,。

  • 連接意義之一是告知協(xié)議棧IP和端口

當創(chuàng)建完套接字以后,,并沒有存放任何的數(shù)據(jù),自然也就不知道和誰說話,。這個時候,,如果應用程序要求發(fā)送數(shù)據(jù),對于協(xié)議棧而言還是一臉懵逼,。只有將IP和端口告知協(xié)議棧,,他才會開始干活

服務端通過Socket庫中的read接收消息,這里注意,,調(diào)用read的時候需要制定用于存放響應消息的內(nèi)存地址,,也叫做接收緩存區(qū)。

  • 連接意義二:

服務端創(chuàng)建套接字,,但是不知道和誰通信,。所以等待客戶端告知'我是XX,我的IP是xxx,端口號是XXX'

具體操作步驟

  • 通過connect將IP地址和端口信息傳遞給協(xié)議棧的TCP模塊,,它會和服務端的TCP模塊交換信息,。具體交換哪些信息呢??蛻舳藴蚀_找到服務端以后,,會將頭部控制位中的SYN置為1。TCP 模塊將信息傳遞給IP模塊并委托它進行發(fā)送,,服務端將接收到的IP模塊傳送給TCP模塊 ,,TCP模塊根據(jù)控制信息找到端口號相同的套接字并將狀態(tài)修改為正在連接。此時將會進行響應,,響應的過程中將ACK控制位設置為1表示已經(jīng)收到對應的網(wǎng)絡包,。TCP屬于全雙工通信,為了盡全力保證網(wǎng)絡傳輸信息的不丟失,,會進行雙方確認機制,。

  • 此時網(wǎng)絡包到達客戶端,通過IP模塊到達TCP模塊,,TCP模塊通過頭部信息確認連接服務器的這個操作是否成果,。如果此時SYN為1則表示連接成功。然后將響應中的ACK設置1告訴服務器你的響應我收到了,。這樣連接操作完成,。控制流程交給應用程序

6 應用階段

當連接后到達應用程序后,,此時將決定我們需要發(fā)送什么數(shù)據(jù) ,,怎么發(fā)數(shù)據(jù),,是按照流的方式還是逐字節(jié)發(fā)送,以及發(fā)什么內(nèi)容,,這樣的多樣性對于協(xié)議棧而言是不怎么關心的,。對于協(xié)議棧,它不會是收到什么數(shù)據(jù)就馬上發(fā)送,,它會將數(shù)據(jù)先暫存緩沖區(qū),,如果收到數(shù)據(jù)就發(fā)送,難免會出現(xiàn)大量的小包,,這樣會讓網(wǎng)絡效率下降。那對于協(xié)議棧而言,,到底一次滿足多少才進行發(fā)送呢,?

  • 根據(jù)MTU判斷

MTU是一個網(wǎng)絡的最大長度,以太網(wǎng)中為1500字節(jié),,減去MTU的頭部長度,,所能容納的最大數(shù)據(jù)長度為1460即MSS。這樣就可避免出現(xiàn)大量的小包問題

在這里插入圖片描述
  • 根據(jù)時間,。

協(xié)議棧內(nèi)部有個計時器,,到達時間就將網(wǎng)絡包發(fā)送出去。

仔細理解這兩點,,你會發(fā)現(xiàn)兩者沖突了,。因為如果考慮長度的優(yōu)先級更高,那么網(wǎng)絡效率高,,但是可能等待緩沖區(qū)的時間比較長,。如果時間優(yōu)先級更高,延遲時間就短,,但是降低了網(wǎng)絡效率,。所以在應用程序中提供了選項,在開發(fā)的過程中可以根據(jù)實際情況進行設置,。

如果HTTP請求消息太長了怎么辦呢,?

數(shù)據(jù)大了則進行拆分,拆分后為了能完整組裝,,每個小塊提前做好標識,。當判斷需要發(fā)送這些數(shù)據(jù)的時候,就在每一塊的數(shù)據(jù)前面加上TCP頭部,,然后交給IP模塊進行數(shù)據(jù)的發(fā)送 ,。

在這里插入圖片描述

ACK確認機制

如果能發(fā)出數(shù)據(jù),但是我們發(fā)了數(shù)據(jù)卻不知道是否已經(jīng)收到,,或者中途有沒有出現(xiàn)損失數(shù)據(jù)卻不知情,。所以,,引入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號的操作,。

滑動窗口

發(fā)送一個包后,,不傻等ACK的返回,,而是繼續(xù)發(fā)送后續(xù)的包,,這樣就充分的利用這段空閑時間,。但是這樣也出現(xiàn)了一個問題,,可能出現(xiàn)發(fā)送包的頻率太快以致于接收方處理不過來出現(xiàn)堆積。

在這里插入圖片描述

首先,,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地址,。

  • 協(xié)議號:代表包從哪個模塊來。如果是TCP模塊則填寫06,,如果是UDP模塊填寫17,。

MAC

生成了IP頭部后,需要在IP頭部加上MAC頭部,,其中包含了接收方和發(fā)送方的MAC地址信息,,因為在以太網(wǎng)的世界里需要按照以太網(wǎng)的規(guī)則辦事兒

在這里插入圖片描述
  • 以太網(wǎng)類型

以太網(wǎng)類型代表后面內(nèi)容的類型,比如如果是IP地址相關則為0800

  • 發(fā)送方MAC地址

MAC地址在網(wǎng)卡生產(chǎn)時就放入ROM中,,取出存放于MAC頭部即可,。

  • 接收方MAC地址

要知道接收方的MAC地址,又需要找?guī)褪至?ARP),,在局域網(wǎng)中大喊一聲“xx這個IP地址是哪個,?麻煩把你的MAC地址告訴我”,此時就有人給予回應'這是我的IP地址,,我的MAC地址是XX',,但是我們不可能每次都一頓喊,,所以就有殺手锏'ARP緩存',,一次詢問后就會保存于緩存表中,下次再來如果能匹配到表就可直接獲取MAC地址,。

此時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頭部,保證格式正確

  • 查看接收方IP,,如果接收的IP地址與客戶端發(fā)送過來IP一致則接受這個包,,否則就很可能除了問題,此時IP模塊會通過ICMP將錯誤告知發(fā)送方,,ICMP包含了哪些錯誤提示呢,,總結如下

在這里插入圖片描述

此時IP模塊交給TCP模塊,TCP模塊根據(jù)IP頭部的接收方和發(fā)送方IP地址,,以及TCP頭部的的發(fā)送,,接收端口信息,組成<發(fā)送地址,,接收地址,,源端口,目的端口>四元組信息查找對應的套接字,,從而可查看通信的狀態(tài)并執(zhí)行相關的通信,。

9 防火墻

看似一切到達服務器還比較順利,順利歸順利,,但是我們的大部分項目中不得不考慮安全因素,,不是什么數(shù)據(jù)包都可以隨便進來,,所以必須使用某種手段過濾掉一部分數(shù)據(jù)包,,這就是防火墻

在這里插入圖片描述

不知道大家用過Tcpdump、Wireshark等工具沒,,它的過濾機制類似于防火墻的原理,,那么為了實現(xiàn)過濾,我們就需要深刻了解各層協(xié)議的頭部構造,,只有熟悉其頭部字段,,才能在過濾表達式中施展魔法。

通過IP 端口等過濾

比如常見明文協(xié)議HTTP使用的80端口,我們可以通過設置IP+端口的方式限制其他數(shù)據(jù)包的通行,。

設置控制位的方式

比如在TCP三次握手的時候會交換或者更新ack syn等信息,,我們則可以通過設置相應位置來達到我們過濾的目的

隨著系統(tǒng)越來與牛逼,收益越來越來,,老板跑來:“小伙計,,用戶反映請求后半天收不到消息誒”。豈不是廢話么,,系統(tǒng)做得好,,跑路少不了,錢不到手,,怎敢跑路,,成,一頓性能測試猛如虎,,哎呀,,加個負載均衡試試?

負載均衡

隨著用戶訪問量的劇增,,單臺服務器明顯感覺到了壓力,,再這樣下去用戶可能直接要干我,同事小A牛逼啊,,上來就是:'上性能高一點的服務器啊',,小B也不賴:“多買幾臺服務器不就完事了?” 好,,我們就聽聽小B的方案

從曾經(jīng)的一臺服務器,,增加到現(xiàn)在到五臺服務器,相當于每臺服務器分擔1/5,,這樣壓力自然小了很多,,那問題來了,怎么才能將請求分散到各臺服務器呢,?哪都有哪些負載均衡的方案,?

砸錢

最初實現(xiàn)負載均衡采取的方案很直接,直接上硬件,,當然也就比較貴,,互聯(lián)網(wǎng)的普及,和各位科學家的無私奉獻,,各個企業(yè)開始部署自己的方案,,從而出現(xiàn)負載均衡服務器

HTTP重定向負載均衡

也屬于比較直接,當HTTP請求到達負載均衡服務器后,,使用一套負載均衡算法計算到后端服務器的地址,,然后將新的地址給用戶瀏覽器,,瀏覽器收到重定向響應后發(fā)送請求到新的應用服務器從而實現(xiàn)負載均衡,如下圖所示

在這里插入圖片描述

優(yōu)點:

  • 簡單,,如果是java開發(fā)工程師,,只需要servlet中幾句代碼即可

缺點:

  • 加大請求的工作量。第一次請求給負載均衡服務器,,第二次請求給應用服務器

  • 因為要先計算到應用服務器的IP地址,,所以IP地址可能暴露在公網(wǎng),既然暴露在了公網(wǎng)還有什么安全可言

DNS負載均衡

了解計算機網(wǎng)絡的你應該很清楚如何獲取IP地址,,其中比較常見的就是DNS解析獲取IP地址,。用戶通過瀏覽器發(fā)起HTTP請求的時候,DNS通過對域名進行即系得到IP地址,,用戶委托協(xié)議棧的IP地址簡歷HTTP連接訪問真正的服務器,。這樣不同的用戶進行域名解析將會獲取不同的IP地址從而實現(xiàn)負載均衡

在這里插入圖片描述

乍一看,和HTTP重定向的方案不是很相似嗎而且還有DNS解析這一步驟,,也會解析出IP地址,,不一樣的暴露?每次都需要解析嗎,,當然不,,通常本機就會有緩存,在實際的工程項目中通常是怎么樣的呢

  • 通過DNS解析獲取負載均衡集群某臺服務器的地址

  • 負載均衡服務器再一次獲取某臺應用服務器,,這樣子就不會將應用服務器的IP地址暴露在官網(wǎng)了

反向代理負載均衡

這里典型的就是Nginx提供的反向代理和負載均衡功能,。用戶的請求直接叨叨反向代理服務器,服務器先看本地是緩存過,,有直接返回,,沒有則發(fā)送給后臺的應用服務器處理。

在這里插入圖片描述

IP負載均衡

上面一種方案是基于應用層的,,IP很明顯是從網(wǎng)絡層進行負載均衡,。TCP./IP協(xié)議棧是需要上下層結合的方式達到目標,當請求到達網(wǎng)絡層的時候,。負載均衡服務器對數(shù)據(jù)包中的IP地址進行轉換,,從而發(fā)送給應用服務器

在這里插入圖片描述

注意,這種方案通常屬于內(nèi)核級別,,如果數(shù)據(jù)比較小還好,,但是大部分情況是圖片等資源文件,這樣負載均衡服務器會出現(xiàn)響應或者請求過大所帶來的瓶頸

數(shù)據(jù)鏈路負載均衡

它可以解決因為數(shù)據(jù)量他打而導致負載均衡服務器帶寬不足這個問題,。怎么實現(xiàn)的呢,。它不修改數(shù)據(jù)包的IP地址,,而是更改mac地址,。應用服務器和負載均衡服務器使用相同的虛擬IP

在這里插入圖片描述

以上介紹了幾種負載均衡的方式,,但是很重要的負載均衡算法卻沒有設計,其中包含了輪詢,,隨機,,最少連接,下面分別對此進行介紹(假設以Nginx為例)

輪詢

輪詢是Nginx中默認的處理負載的方式,,從方式名稱應該可以猜出輪詢即輪流的分配到后端的服務上,。舉個例子來說,假設目前后端有4臺服務器,,此時過來6個連接,,如果采用輪詢的方式,他就是這樣工作A->1,,B->2,,C->3,D->4,,A->5,,B->6

upstream XXX{
        server localhost:8081;
        server localhost:8082;
        server localhost:8083;
    }

    server {
        listen 80;
        server_name www.;
        location /{
            proxy_pass http://xxx;
        }
    }

Hash方式*處理公式:abs(客戶端ip.hash())%服務器數(shù)量*

因為客戶端的ip地址是唯一不變的,所以,,通過hash算法計算出ip地址對應的哈希碼值,,通過哈希碼值對服務器的數(shù)量進行一個求模運算。這樣就可以保證每個客戶端訪問的服務器都是保持不變的,,因為hash算法的散列特點,,也可以近似的當作平均分配。

upstream H_xx{
        ip_hash;
        server localhost:8081;
        server localhost:8082;
        server localhost:8083;
    }

    server {
        listen 80;
        server_name www.;
        location /{
            proxy_pass http://H_xx;
        }

出現(xiàn)的問題

Hash算法中的散列特點,,會導致某臺服務器請求量過高,,其他服務器請求卻很少的情況。比如A服務器處理請求1000,,而B服務器請求只有80,,C服務器請求為20。我們希望后面的請求盡量來C服務器,,所以出現(xiàn)了下面的方案

最小連接方式

采用這種方式,,Nginx會將請求發(fā)送給當前處理請求數(shù)量最少的服務器從而緩解集群的壓力

upstream XXX{
        leash_conn;
        server localhost:8081;
        server localhost:8082;
        server localhost:8083;
    }

    server {
        listen 80;
        server_name www.;
        location /{
            proxy_pass http://XXX;
        }
    }

既然是將請求分給目前連接數(shù)最少的服務器,那好,,我們看看這種情況,。A服務器買的比較早,承受的并發(fā)數(shù)為200,,B服務器稍微能承受的服務器并發(fā)數(shù)高一點500,,C服務器能承受的并發(fā)數(shù)為1000。目前各個服務器情況如何呢,?此時A服務器已經(jīng)處理了199個連接,,B服務器處理了499個連接,,C服務器處理了500個連接,我們當然希望接下來的請求交給C服務器處理,,不然對于AB而言豈不是壓死了最后一根稻草,,所以出現(xiàn)下面這種方式

基于權重的方式

通過設置權重的方式合理分配請求連接數(shù)

upstream XXX{
        server localhost:8081 weight=6;
        server localhost:8082 weight=2;
        server localhost:8083 down;
    }

    server {
        listen 80;
        server_name www.;
        location /{
            proxy_pass http://xxx;
        }
    }

此時通過weight權重進行資源的分配。down表示當前服務器不參加負載均衡,。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多