高并发负载均衡——网络协议原理
一、網(wǎng)絡(luò)分層模型
軟件工程項目學(xué)中有一個重要的思想就是分層解耦。OSI七層模型,TCP/IP四層(有時將數(shù)據(jù)鏈路層和物理層分開稱為五層模型),都是為了更好的實現(xiàn)網(wǎng)絡(luò)的互通。
應(yīng)用層:網(wǎng)絡(luò)服務(wù)于最終用戶的一個接口,Tomcat、瀏覽器都屬于這一層。
表示層:數(shù)據(jù)的表示、安全(加解密)、壓縮等處理。
會話層:建立、管理、終止會話。
傳輸層:定義數(shù)據(jù)傳輸?shù)膮f(xié)議端口號,以及流控和差錯校驗。
網(wǎng)絡(luò)層:進(jìn)行邏輯地址尋址,實現(xiàn)不同網(wǎng)絡(luò)之間的路由。
數(shù)據(jù)鏈路層:建立邏輯連接、進(jìn)行硬件地址尋址、差錯校驗等。
物理層:建立、維護(hù)、斷開物理連接。
二、網(wǎng)絡(luò)數(shù)據(jù)傳輸示例
通過Linux系統(tǒng)的Shell交互程序?qū)崿F(xiàn)百度首頁的請求。
首先進(jìn)入當(dāng)前shell程序的文件描述符定義路徑,其中$$是當(dāng)前命令解釋程序(即Shell)。
0 1 2分別代表輸入、輸出和報錯,這是所有交互程序都必須具備的接口。
使用exec命令,建立一個文件描述符8,代表一個socket連接:
此時,我們已經(jīng)對www.baidu.com建立了一個TCP連接,緊接著,手寫一個最簡HTTP請求,輸出到Socket中,并通過輸入流從socket中取出響應(yīng),并輸出。
最后關(guān)閉socket:
通過echo打印的 HTTP協(xié)議頭字符串,就是在模擬應(yīng)用層服務(wù)(如瀏覽器)的請求封裝工作。但實際上,并不是應(yīng)用層服務(wù)直接將請求發(fā)出,而是通過更下層的服務(wù)層層包裝、尋址完成的。每一層都有對應(yīng)的協(xié)議,上層服務(wù)只需要將請求內(nèi)容按照協(xié)議組織好后就可以調(diào)用傳輸層服務(wù),并通過網(wǎng)絡(luò)接口發(fā)送出去。
應(yīng)用層屬于用戶態(tài),傳輸層以下是內(nèi)核態(tài)。Java應(yīng)用程序在請求網(wǎng)絡(luò)時,就是像上面這樣,獲取一個socket對象,然后將封裝好的信息放入其中。JVM如果想要建立一個網(wǎng)絡(luò)連接,我們通過代碼new Socket,但實際上底層都是native接口,是JVM去請求了系統(tǒng)調(diào)用,待操作系統(tǒng)內(nèi)核跑完底層,返回一個建立成功的連接,之后才能執(zhí)行下一步代碼。在建立連接的時候,程序一定是會出現(xiàn)一定的阻塞。
三、傳輸層的TCP協(xié)議
TCP協(xié)議是傳輸層的重要協(xié)議,是面向連接的、可靠的通信標(biāo)準(zhǔn)。它通過三次握手、四次揮手機制實現(xiàn)安全可靠的連接。
3.1 三次握手
上圖是三次握手的模型。
① 客戶機首先發(fā)送第一次請求,主要參數(shù)有SYN、seq ;
② 服務(wù)器收到請求后,發(fā)送第二次請求給客戶機,這實際上是上一次客戶機請求的確認(rèn)響應(yīng),但同時也是服務(wù)器對客戶機的請求,參數(shù)主要有SYN、ACK、seq。
③ 客戶機收到響應(yīng)后,會再次確認(rèn)這個響應(yīng),遞增相關(guān)參數(shù)并響應(yīng)回去。
經(jīng)過了一次原始請求和兩次確認(rèn)的通信之后,我們就已經(jīng)可以認(rèn)為這是一次明確、可靠的連接。
三趟數(shù)據(jù)包走完之后,雙方才會在內(nèi)存中開辟線程,開辟對象,開辟所有的描述符,建立相應(yīng)的資源,而如果三次握手失敗,這些資源是不會開辟的。
3.2 四次揮手
四次揮手?jǐn)嚅_連接,請求方發(fā)送斷開請求,接收響應(yīng),但此時并未斷開,需要由被動方主動發(fā)起允許斷開的通知,方可完成斷開操作。即先告知斷開請求,再由被動方斷開,最后雙方釋放資源,如端口號等。
整體通訊過程大致為:
三次握手-->數(shù)據(jù)傳輸-->四次分手
這個通訊過程是一個最小粒度,不可被分割。類似事務(wù)原子性。例如,在多負(fù)載系統(tǒng)中,多個實例不可以拆分同一個TCP連接,即端點與端點的所有數(shù)據(jù)請求、響應(yīng)都不可以被任何負(fù)載技術(shù)所打散。
3.3 Linux下查看TCP 連接狀態(tài)
netstat命令:
-n:numeric 直接使用ip地址,不通過域名服務(wù)器
-a:all 顯示所有連線中的socket
-t:tcp
-p: 顯示PID及對應(yīng)程序
我們通過終端軟件進(jìn)行ssh登錄后,就可以看到netstat的網(wǎng)絡(luò)連接狀態(tài):
響應(yīng)表格中,LISTEN表示正在監(jiān)聽,ESTABLISHED表示已經(jīng)建立連接,所謂的Socket,就是Local Address和Foreign Address組成的一條唯一值。
其中有三條sshd程序,第一條sshd是父進(jìn)程,處于LISTEN狀態(tài),一旦監(jiān)聽到連接請求,那么就會拋出一個線程用于建立Socket連接,后面兩個sshd分別是遠(yuǎn)程終端的圖形交互窗口sftp連接和命令行窗口ssh連接,Foreign Address中的192.168.1.1實際上就是Windows上的虛擬網(wǎng)卡,而port是隨機的。
四、網(wǎng)絡(luò)層
4.1 Linux網(wǎng)卡配置及IP下一跳機制
我們查看eth0網(wǎng)卡的配置信息,一般主要關(guān)注四個維度:
ip地址、掩碼、網(wǎng)關(guān)、DNS服務(wù)地址。
查看路由表:
在很早的以前的網(wǎng)絡(luò)拓?fù)洚?dāng)中,有一種模型,是每臺主機都存儲一個全局的網(wǎng)絡(luò)拓?fù)?#xff0c;這種模型會隨著互聯(lián)網(wǎng)上的設(shè)備增多而失去可行性,于是就產(chǎn)生了現(xiàn)在的網(wǎng)絡(luò)尋址機制,即下一跳機制。
所謂“下一跳”,就是當(dāng)前IP地址到達(dá)目標(biāo)IP的路徑上臨近的下一個IP地址。在路由過程中,數(shù)據(jù)包到達(dá)每個主機都會進(jìn)行路由判定,并依次轉(zhuǎn)發(fā)。這些轉(zhuǎn)發(fā)的路徑需要網(wǎng)絡(luò)工程師來進(jìn)行規(guī)劃。下一跳機制可以極大的減少主機需要存儲的IP地址信息,只需要記住同一網(wǎng)絡(luò)的網(wǎng)關(guān)地址,就可以了。
4.2?通過ping理解下一跳機制
通過ping命令(基于ICMP協(xié)議)可以判斷主機的連通狀態(tài),如下是ping百度首頁:
那么ping程序是如何將數(shù)據(jù)包發(fā)送到遙遠(yuǎn)的百度服務(wù)器的呢?
首先,ping命令拿著目標(biāo)地址(39.156.66.14)逐條與路由表中的掩碼進(jìn)行按位與運算,并且與Destination進(jìn)行比較,這就是路由判定。如果目標(biāo)地址與Destination記錄的IP一致,就將數(shù)據(jù)包發(fā)給它。
上圖中,經(jīng)過路由判定,Destination=0.0.0.0符合要求,于是,我們就得到了下一跳地址192.168.1.2。而實際上不論什么IP,只要和掩碼為0.0.0.0進(jìn)行與運算,就都會得到0.0.0.0,因此在上面的路由表中192.168.1.2 就是默認(rèn)網(wǎng)關(guān)。
互聯(lián)網(wǎng)中的所有設(shè)備都會存儲這樣的路由表,只要具備轉(zhuǎn)發(fā)能力,都會進(jìn)行路由判定。一般的小型路由設(shè)備都會有一條默認(rèn)的下一跳地址,而對于一些骨干網(wǎng)、城域網(wǎng)等大型網(wǎng)絡(luò)環(huán)境,網(wǎng)絡(luò)工程師可能會設(shè)置更多的下一跳條目,規(guī)劃通信路由。
網(wǎng)關(guān)可以有多個,但是默認(rèn)網(wǎng)關(guān)只有一個。同一網(wǎng)絡(luò)通信是不需要路由設(shè)備的,只需要簡單的交換機即可實現(xiàn)數(shù)據(jù)轉(zhuǎn)發(fā),只有不同網(wǎng)絡(luò)的通信才需要下一跳地址。
五、數(shù)據(jù)鏈路層
當(dāng)網(wǎng)絡(luò)層的路由判定找到了下一跳地址,但數(shù)據(jù)包中的目標(biāo)地址永遠(yuǎn)是最終將要發(fā)送到的IP地址,又如何將數(shù)據(jù)包發(fā)送到下一跳呢?
在IP數(shù)據(jù)包之外,又“包裹”了一層協(xié)議包。數(shù)據(jù)鏈路層同樣存在一張表格,記錄了MAC地址:
DNS是解釋域名和IP地址的映射,arp協(xié)議會解釋IP地址到MAC地址的映射。但前者是全網(wǎng)的,而arp是同一局域網(wǎng)內(nèi)的。
經(jīng)過arp的地址判定,IP數(shù)據(jù)包外面會“包裹”一個下一跳的MAC地址,這時整個數(shù)據(jù)包內(nèi)部存在三個地址:下一跳的MAC地址、目標(biāo)IP地址,以及目標(biāo)端口號。
總結(jié)
TCP是重要的網(wǎng)絡(luò)通信手段,三次握手建立的連接是一個可靠的Socket信道,這些信息可以通過 netstat -natp 命令查看。
IP數(shù)據(jù)包會記錄目標(biāo)地址的IP,傳輸過程中并不會改變。通過路由判定找到下一跳的網(wǎng)絡(luò)IP地址,再通過數(shù)據(jù)鏈路層的 arp 協(xié)議找到下一跳IP的MAC地址,將其包裹在IP數(shù)據(jù)包外面,并通過物理層發(fā)送到下一跳。最終發(fā)送到IP數(shù)據(jù)包內(nèi)的目標(biāo)地址的目標(biāo)端口上。
下一跳機制極大的減少了主機需要記錄的通信IP數(shù)據(jù),但同時,需要網(wǎng)絡(luò)工程師對下一跳進(jìn)行網(wǎng)絡(luò)規(guī)劃,開通相應(yīng)策略,就像是搭建一個網(wǎng)絡(luò)上的路由橋梁,連接各個網(wǎng)絡(luò)之間的通信。
總結(jié)
以上是生活随笔為你收集整理的高并发负载均衡——网络协议原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux进阶之路————用户管理
- 下一篇: Java8————Stream API