談一談你對TCP/IP四層模型,OSI七層模型的理解?
為了增強通用性和相容性,計算機網路都被設計成層次機構,每一層都遵守一定的規則。
因此有了OSI這樣一個抽象的網路通訊參考模型,按照這個標準使計算機網路系統可以互相連線。
物理層:通過網線、光纜等這種物理方式將電腦連線起來。傳遞的資料是位元流,0101010100。
資料鏈路層: 首先,把位元流封裝成資料幀的格式,對0、1進行分組。電腦連線起來之後,資料都經過網路卡來傳輸,而網路卡上定義了全世界唯一的MAC地址。然後再通過廣播的形式向區域網內所有電腦傳送資料,再根據資料中MAC地址和自身對比判斷是否是發給自己的。
網路層:廣播的形式太低效,為了區分哪些MAC地址屬於同一個子網,網路層定義了IP和子網掩碼,通過對IP和子網掩碼進行與運算就知道是否是同一個子網,再通過路由器和交換機進行傳輸。IP協議屬於網路層的協議。
傳輸層:有了網路層的MAC+IP地址之後,為了確定資料包是從哪個程式傳送過來的,就需要埠號,通過埠來建立通訊,比如TCP和UDP屬於這一層的協議。
會話層:負責建立和斷開連線
表示層:為了使得資料能夠被其他的計算機理解,再次將資料轉換成另外一種格式,比如文字、視訊、圖片等。
應用層:最高層,面對使用者,提供計算機網路與最終呈現給使用者的介面
TCP/IP則是四層的結構,相當於是對OSI模型的簡化。
- 資料鏈路層,也有稱作網路訪問層、網路介面層。他包含了OSI模型的物理層和資料鏈路層,把電腦連線起來。
- 網路層,也叫做IP層,處理IP資料包的傳輸、路由,建立主機間的通訊。
- 傳輸層,就是為兩臺主機裝置提供端到端的通訊。
- 應用層,包含OSI的會話層、表示層和應用層,提供了一些常用的協議規範,比如FTP、SMPT、HTTP等。
總結下來,就是物理層通過物理手段把電腦連線起來,資料鏈路層則對位元流的資料進行分組,網路層來建立主機到主機的通訊,傳輸層建立埠到埠的通訊,應用層最終負責建立連線,資料格式轉換,最終呈現給使用者。
說說TCP 3次握手的過程?
建立連線前server端需要監聽埠,所以初始狀態是LISTEN。
- client端建立連線,傳送一個SYN同步包,傳送之後狀態變成SYN_SENT
- server端收到SYN之後,同意建立連線,返回一個ACK響應,同時也會給client傳送一個SYN包,傳送完成之後狀態變為SYN_RCVD
- client端收到server的ACK之後,狀態變為ESTABLISHED,返回ACK給server端。server收到之後狀態也變為ESTABLISHED,連線建立完成。
為什麼要3次?2次,4次不行嗎?
因為TCP是雙工傳輸模式,不區分客戶端和服務端,連線的建立是雙向的過程。
如果只有兩次,無法做到雙向連線的建立,從建立連線server回覆的SYN和ACK合併成一次可以看出來,他也不需要4次。
揮手為什麼要四次?因為揮手的ACK和FIN不能同時傳送,因為資料傳送的截止時間不同。
那麼四次揮手的過程呢?
- client端向server傳送FIN包,進入FIN_WAIT_1狀態,這代表client端已經沒有資料要傳送了
- server端收到之後,返回一個ACK,進入CLOSE_WAIT等待關閉的狀態,因為server端可能還有沒有傳送完成的資料
- 等到server端資料都傳送完畢之後,server端就向client傳送FIN,進入LAST_ACK狀態
- client收到ACK之後,進入TIME_WAIT的狀態,同時回覆ACK,server收到之後直接進入CLOSED狀態,連線關閉。但是client要等待2MSL(報文最大生存時間)的時間,才會進入CLOSED狀態。
為什麼要等待2MSL的時間才關閉?
- 為了保證連線的可靠關閉。如果server沒有收到最後一個ACK,那麼就會重發FIN。
- 為了避免埠重用帶來的資料混淆。如果client直接進入CLOSED狀態,又用相同埠號向server建立一個連線,上一次連線的部分資料在網路中延遲到達server,資料就可能發生混淆了。
TCP怎麼保證傳輸過程的可靠性?
校驗和:傳送方在傳送資料之前計算校驗和,接收方收到資料後同樣計算,如果不一致,那麼傳輸有誤。
確認應答,序列號:TCP進行傳輸時資料都進行了編號,每次接收方返回ACK都有確認序列號。
超時重傳:如果傳送方傳送資料一段時間後沒有收到ACK,那麼就重發資料。
連線管理:三次握手和四次揮手的過程。
流量控制:TCP協議報頭包含16位的視窗大小,接收方會在返回ACK時同時把自己的即時視窗填入,傳送方就根據報文中視窗的大小控制傳送速度。
擁塞控制:剛開始傳送資料的時候,擁塞視窗是1,以後每次收到ACK,則擁塞視窗+1,然後將擁塞視窗和收到的視窗取較小值作為實際傳送的視窗,如果發生超時重傳,擁塞視窗重置為1。這樣做的目的就是為了保證傳輸過程的高效性和可靠性。
說下瀏覽器請求一個網址的過程?
- 首先通過DNS伺服器把域名解析成IP地址,通過IP和子網掩碼判斷是否屬於同一個子網
- 構造應用層請求http報文,傳輸層新增TCP/UDP頭部,網路層新增IP頭部,資料鏈路層新增乙太網協議頭部
- 資料經過路由器、交換機轉發,最終達到目標伺服器,目標伺服器同樣解析資料,最終拿到http報文,按照對應的程式的邏輯響應回去。
知道HTTPS的工作原理嗎?
- 使用者通過瀏覽器請求https網站,伺服器收到請求,選擇瀏覽器支援的加密和hash演算法,同時返回數字證書給瀏覽器,包含頒發機構、網址、公鑰、證書有效期等資訊。
- 瀏覽器對證書的內容進行校驗,如果有問題,則會有一個提示警告。否則,就生成一個隨機數X,同時使用證書中的公鑰進行加密,並且傳送給伺服器。
- 伺服器收到之後,使用私鑰解密,得到隨機數X,然後使用X對網頁內容進行加密,返回給瀏覽器
- 瀏覽器則使用X和之前約定的加密演算法進行解密,得到最終的網頁內容
負載均衡有哪些實現方式?
DNS:這是最簡單的負載均衡的方式,一般用於實現地理級別的負載均衡,不同地域的使用者通過DNS的解析可以返回不同的IP地址,這種方式的負載均衡簡單,但是擴充套件性太差,控制權在域名服務商。
Http重定向:通過修改Http響應頭的Location達到負載均衡的目的,Http的302重定向。這種方式對效能有影響,而且增加請求耗時。
反向代理:作用於應用層的模式,也被稱作為七層負載均衡,比如常見的Nginx,效能一般可以達到萬級。這種方式部署簡單,成本低,而且容易擴充套件。
IP:作用於網路層的和傳輸層的模式,也被稱作四層負載均衡,通過對資料包的IP地址和埠進行修改來達到負載均衡的效果。常見的有LVS(Linux Virtual Server),通常效能可以支援10萬級併發。
按照型別來劃分的話,還可以分成DNS負載均衡、硬體負載均衡、軟體負載均衡。
其中硬體負載均衡價格昂貴,效能最好,能達到百萬級,軟體負載均衡包括Nginx、LVS這種。
說說BIO/NIO/AIO的區別?
BIO:同步阻塞IO,每一個客戶端連線,服務端都會對應一個處理執行緒,對於沒有分配到處理執行緒的連線就會被阻塞或者拒絕。相當於是一個連線一個執行緒。
NIO:同步非阻塞IO,基於Reactor模型,客戶端和channel進行通訊,channel可以進行讀寫操作,通過多路複用器selector來輪詢註冊在其上的channel,而後再進行IO操作。這樣的話,在進行IO操作的時候再用一個執行緒去處理就可以了,也就是一個請求一個執行緒。
AIO:非同步非阻塞IO,相比NIO更進一步,完全由作業系統來完成請求的處理,然後通知服務端開啟執行緒去進行處理,因此是一個有效請求一個執行緒。
那麼你怎麼理解同步和阻塞?
首先,可以認為一個IO操作包含兩個部分:
- 發起IO請求
- 實際的IO讀寫操作
同步和非同步在於第二個,實際的IO讀寫操作,如果作業系統幫你完成了再通知你,那就是非同步,否則都叫做同步。
阻塞和非阻塞在於第一個,發起IO請求,對於NIO來說通過channel發起IO操作請求後,其實就返回了,所以是非阻塞。
談一下你對Reactor模型的理解?
Reactor模型包含兩個元件:
- Reactor:負責查詢、響應IO事件,當檢測到IO事件時,分發給Handlers處理。
- Handler:與IO事件繫結,負責IO事件的處理。
它包含幾種實現方式:
單執行緒Reactor
這個模式reactor和handler在一個執行緒中,如果某個handler阻塞的話,會導致其他所有的handler無法執行,而且無法充分利用多核的效能。
單Reactor多執行緒
由於decode、compute、encode的操作並非IO的操作,多執行緒Reactor的思路就是充分發揮多核的特性,同時把非IO的操作剝離開。
但是,單個Reactor承擔了所有的事件監聽、響應工作,如果連線過多,還是可能存在效能問題。
多Reactor多執行緒
為了解決單Reactor的效能問題,就產生了多Reactor的模式。其中mainReactor建立連線,多個subReactor則負責資料讀寫。
- END -