動態

詳情 返回 返回

百萬架構師第二十五課:分佈式架構的基礎:分佈式系統的基石TCP-IP通訊協議|JavaGuide - 動態 詳情

原文鏈接
  1. 通訊協議在分佈式架構中的核心應用
  2. 深入料及TCP/IP和UDP/IP通信協議
  3. TCP流量整形
  4. 基於Java自身技術實現系統通訊
  5. 多任務處理及優化
  6. 瞭解什麼是NIO
  7. 組播協議 Multicast

從集中式的架構到分佈式架構粗粒度的架構模型圖

從集中式的架構到分佈式架構粗粒度的架構模型圖

相當於是在整個架構層面上去做一個分層,分層以後會存在按照某一個領域去切分的服務層,存在web層。

​ 如果我們以前是在一個獨立的服務模型裏邊,不需要涉及遠程通信,唯一的遠程通訊就是客户端和遠程端的通訊,現在變成一個分佈式架構,那麼就意味着:服務層之間彼此會通訊,這樣一個通訊的話,就會涉及到一個通訊協議,比如我們現在Web層調用Dubbo層是通過Dubbo協議去調用的,然後Dubbo調用基礎服務,是通過socked的TCP通訊去完成一些服務間的對接。

​ 這是通訊在整個分佈式架構中的用途。

​ 如果説沒有一個遠程通信的話,就意味着我們的分佈式架構就沒有存在的意義和價值。

所以説:

​ 在整個架構裏邊,通信會涉及協議、序列化、網絡通信協議底層的TCP協議和UDP協議。

任務目標

怎麼完成一個遠程通信???

如果沒有遠程通信,就沒有所謂的分佈式系統,我們發送一個消息,會被某一個接收端去接收,那這個消息的形式有很多種。

傳輸的數據類型

1. 字節流

2. 字節數組

3. java對象

協議類型

外部的系統收到這樣一個請求以後需要做一個相應的處理,那這種基於消息方式的通信,在我們的網絡層裏邊,一般來説就涵蓋兩種。

  1. TCP/IP協議
  2. UDP/IP協議

網絡領域的知識

協議:

TCP/UDP/multicast

IO

遠程通信一定涉及IO的形式(BIO、NIO、AIO)

Socket

套接字

NIO

(Netty/Mina)

序列化和反序列化

在網絡通信中需要傳輸一個對象的話,就涉及序列化和反序列化了。

一個Http請求在整個網絡中的請求過程

基於OSI的七層網絡模型

( 應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層、物理層)

TCP/IP的四層概念模型

​ ( 網絡接口層、網絡層、傳輸層、應用層)

網絡為什麼要分層,以及在通信時,我們的數據是怎麼去傳輸的。

首先是我們打開一個瀏覽器,瀏覽一個網站,這時候相當於應用程序和客户端會產生一個交互。交互就是 TCP的三次握手協議。握手協議是建立一個連接。那在整個通信過程中,數據到底是怎麼一個傳輸方式呢?

一個請求四層協議的發送步驟

先增加一個TCP頭,表示一個協議頭,

第二個增加IP頭,因為IP地址是網卡在網絡中的一個通訊地址,相當於要給門牌號,有時候會提示IP地址衝突,因為IP地址是不能衝突的,相當於小區內部的門牌號,是我們網卡的唯一的通訊地址,相當於我們的門牌號。

增加MAC頭,MAC頭是我們的網卡地址,標識的是這個數據包要發送到的網卡地址,增加的IP頭是目標的IP頭,它本身自帶當前的源IP頭。

到了物理層,轉換成一個Byte流進行一個傳輸,通過網絡通訊進行一個傳輸。

比作寄包裹的話:

  • 選擇快遞公司

    • 地方,省市

      • 姓名,門牌號

IP定位到地方,MAC頭定位到它是發給你的,

IP協議,提供了一組數據報文服務,每組服務都是由網絡統一處理分發的

IP頭有兩個東西,一個目的IP地址,一個源IP地址。

接收方的接收步驟

一個請求四層協議的接收步驟

​ 當我們的目標主機收到這樣一個目標以後,收到網絡上的一個數據幀以後,它就會開始從協議層由底向上升。先到網卡,有兩種形式,一種是所有數據包都接收,一種是,先判斷這個MAC頭是不是我的,如果不是我的就不會進來。所以拿到這個數據以後,到數據鏈路層去摘取這個MAC頭,去判斷當前的一個網卡地址,和發送的MAC是不是匹配。

​ 網絡層,會摘取IP頭,如果不是自己的就會做一個轉發,最後到了傳輸層。協議層會攜帶端口號,通過端口號,定位到具體的進程內,把這個數據包發送到我們對應的接收端。

MAC頭是唯一的,理論上是可以通過MAC頭去發送消息,MAC就像身份證一樣,他是一個唯一的,但是我要去定位,是用IP去定位到我要發送到那個服務器,是個分層結構!

​ 網絡是一個分層,它會有四層。

IP協議

TCP/UDP協議都是基於IP網絡協議之上的,IP協議會提供一組數據報文服務,每組報文會由網絡去統一處理和分發的。

每組報文都必須包含目的地址的地址段、IP層地址段。

IP協議,不可靠,盡力而為的協議,報文丟失,無序,或者説重複發送的情況。

TCP可靠協議

UDP不可靠協議

TCP頭裏邊有目標端口號

協議

協議是兩種網絡通訊中達成的一個約定。

協議目的:

就是規範好通訊之間的約定。

http

超文本傳輸協議

拿到服務器上不同格式的數據

返回給瀏覽器,去做一個解析。(html/json/xml/jpg/png)

基於約定,拿到我想要拿到的東西,就是協議。

請求DNS地址-拿到服務器上的內容

實現一個對我們產生作用的網絡,必須解決一些問題,為了讓這些問題便於管理和模塊化。

基於模塊化的東西,設計了兩種協議

TCP協議

能夠檢測和恢復IP層提供的主機和主機的通訊中可能發生的報文丟失,重複和錯誤的情況。解決了數據丟失、重複發送的問題,提供了可以信賴的字節流通道。

UDP

不可信的協議,不會對協議進行改造修復,提供了一個擴展於IP之上的盡力而為的數據報文服務。能夠提供應用之間的工作,而不是主機之間的工作。不會解決數據丟失和重複,和順序混亂的問題。

用户輸入域名,解析出ip,http請求報文

深入分析 TCP/IP

1) DNS解析

2) 網關進行數據傳輸

3) 路由協議

4) 握手協議

DNS解析

DNS解析得到IP地址,由網關進行數據傳輸,由路由協議傳輸到目的端。

(就像打電話,喂,你好,你好,我是…… 我是…… 就是我們的握手協議)

​ 握手協議防止了數據包的丟失。

TCP通過三次握手建立一個可靠的通道。

三次握手

相當於客户端和服務端進行通信時有三個數據包。

三個狀態:SYN-SEND >> SYN-RCVD >> ESTAB-LISHED

三次握手SYN攻擊

SYN攻擊

在短時間內客户端偽造大量不存在的ip地址,發送給服務端

服務端發送給客户端之後,客户端的確認包一直不發給service,這時候存在大量的連接是空閒的,會消耗我們的資源,導致我們很多正常的請求沒有辦法進去,因為隊列滿了。

TCP協議斷開:

四次揮手協議:

FIN_WAIT_1 CLOSE_WAIT FIN_WAIT2 LAST_WAIT TIME_WAIT.

客户端請求關閉發送給服務端,服務端發送ACK告訴客户端,我收到你的請求了,然後服務端全部請求處理完畢以後發送FIN到客户端,客户端收到FIN報文以後就代表我可以關閉這個連接了,服務端沒有收到ACK,就可以重新傳輸,客户端在兩個生命週期以內沒有收到回覆,服務端就已經關閉了,客户端也可以關閉了。

四次揮手協議步驟

為什麼三次四次:

​ 接收端接收到報文以後可以直接告訴發送端,我收到你的消息了,

​ 關閉的時候,服務器知道告訴發送端,你發送的請求我收到了,我要等到連接處理完,才處理完。

TCP協議,全雙工協議。

發送時間在兩個報文的生命週期內,

協議是建立連接,建立連接之後通訊,針對會話發送數據包,發送數據包,基於這個協議去傳輸。如果接收方不及時接收的情況,發送方應該是可以調控的。

如果接收方不及時處理的時候,發送方是可以控制的。

TCP流量控制

滑動窗口,是一種流量控制技術,

為什麼用滑動窗口

  1. 保證數據不會丟失
  2. 網絡擁塞的情況下會存在數據阻塞

所以在這樣的情況下,引入了滑動窗口,去對我們的流量去做一個整形

動態地址:

http://media.pearsoncmg.com/aw/ecs_kurose_compnetwork_7/cw/co...

發送端-接收端-TCP緩衝區

緩衝區是有大小的,控制流量,

緩衝區的大小就是窗口大小,發送消息,收到ack以後就可以發送下一個窗口

可以設置緩衝區的大小。

根據接收端的緩衝區可以動態調整窗口大小,

發送窗口,允許發送的數據幀的數據量的大小,

接收窗口,

沒有收到消息,會重新發,

TCP緩衝區發送緩衝區

TCP緩衝區發送接收

TCP緩衝區發送接收ACK

TCP緩衝區發送繼續發送

TCP緩衝區發送再次發送

使用TCP協議進行通訊

協議層之上就是應用,協議這塊會很複雜

在現在的編程語言中,提供很完整的機制,屏蔽複雜過程,便於開發應用程序

TCP、UDP都是基於socket概念上為某一個應用場景擴展出來的協議。

什麼是Socket

socket可以認為是一個抽象層,應用程序通過它來發送和接收消息。

這個時候通過應用程序打開文件句柄,讀取數據磁盤,或者把數據寫入到磁盤上。

使用socket可以把我們的應用程序添加到網絡上,而且能跟和它處於一個網絡的應用去通信,這就是socket。

不同的類型的socket和底層的協議是有關係的。

Stream socket(TCP) 字節流
datagram socket (UDP) 數據報文

APP通過Socket和服務端通信

Socket 套接字。

基於socket 選擇協議(TCP [1-65535端口] UDP),然後帶上IP(基於IP協議)

Netty是一個基於NIO的框架

TCP協議是一個全雙工的協議

BIO

Client-Server-BIO圖解

BIO 是一個客户端請求分配一個線程

Client-Server-BIO圖解-Server-Thread

BIO 阻塞

緩衝區被佔用

TCP協議是一個基於緩衝區,內核裏邊都會有個發送緩衝區,接收緩衝區,TCP的全雙工模式是以TCP的滑動窗口,和依賴於這兩個獨立的緩衝區的填充狀態,去處理的, 接收緩衝區把數據緩存到內核裏邊,如果説應用程序,沒有調用read方法去讀取的話,就會存在我們的接收緩衝區裏邊,這個緩衝區都不會被清理掉。

我們接收端receive去調用read去讀取數據,實際上就是把內核讀取到的數據複製到我們應用程序的buffer裏邊,再做一個處理。

進程裏邊調用socket去發送數據

TCP-發送端-接收端-TCP緩衝區

在IO層存在一個IO的調度線程去不斷掃描Socket緩衝區。

發現寫某個寫入緩衝區為空,掃描到了就可以產生一個socket可寫事件,我們的程序就可以對數據進行socket寫入。如果一次寫入沒有寫完,等下次寫入再去寫。

(Epoll Selector機制)

當接收端發現socket接收緩衝區有數據時,會產生socket可讀事件,即使緩衝區滿了,我也可以去接收其他請求。

有一個事件通知,可以讀取這個數據

NIO

​ 發現你不可寫,會有一個事件通知,我這個事件告訴你什麼時候可以寫了,然後我就可以去調用,去做一個處理消息的過程。

​ 就是 Epoll 和 Selector 模型的概念。

​ New IO或者no black IO;

NIO 非阻塞通信 (Non-blocking I/O,在Java領域,也稱為New I/O)

通過一個事件機制,實現解耦

多路複用基於的是NIO機制。

  • 客户端:都註冊一個channel
  • 客户端:都註冊一個channel

NIO以多路複用為基礎。服務端有一個多路複用器,輪詢每一個channel。選擇一個具備已經能夠運行任務的能力的channel。如果某個註冊上來的channel上的TCP產生了一個可寫事件的話,那麼就能夠被輪詢出來,去做一個執行。如果滿足狀態,執行相應的機制,然後不斷地輪詢。

Client-Server-NIO圖解

產生socket可寫事件

組播協議

單播協議

TCP UDP 都是基於點對點的通訊, 可以稱為單播協議。

廣播

網絡中的所有的主機都可以收到一份數據副本

多播

消息只發送給一個多播地址,網絡會把數據發送給那些想要監聽的主機

只有訂閲了這個感興趣的主機才能收到

廣播:

子網主機發送消息,子網內的主機都能收到信息

NIO是基於IO的更好性能的技能

Java本身提供了NIO技術,netty基於NIO做了一個封裝,提供了一個更優化的功能而已。

來源於: https://javaguide.net

公眾號:不止極客

Add a new 評論

Some HTML is okay.