計算機網絡協議——牆都不服,就服你係列

原文連接html

 

DDB:Distributed date base,分佈式數據庫python

RDS:Relational Datebase Service,關係型數據庫服務nginx

CDN:Content Delivery Network,內容分發網絡算法

VPC:Virtual Private Cloud,虛擬私有云。數據庫

  雲端數據中心編程

Subnet:Subnet 子網。網絡的一部分。它是物理上獨立的網絡段,與網絡其它部分共享網絡地址,並用子網號區分。json

可用區(Available Zone):穩定性,可擴展性後端

  可用區:機櫃=1:n瀏覽器

  機櫃:服務器=1:n緩存

接入層交換機:訪問服務器權限的管理

匯聚層交換機:

核心交換機:

 

組織嚴格,井井有條

每一層都是分組看護,互相監督,互相備份,稱爲堆疊。

 

VPC:Virtual Private Cloud,虛擬私有云

  防止信息被盜

Openvswitch的虛擬交換機:信息轉換的做用。

  信息在虛擬私密空間和物理空間之間的轉換做用

  Openvswitch如何轉換呢?使用的是一種稱爲VXLAN的封裝技術,可是必需要事先知道芝麻開門的ID,也即VXLAN ID,才能看到信息的真正內容。

  在虛擬的空間中,放着真正能夠解讀的信息。

微服務架構:

  前中後臺分離,分爲基礎服務層,組合服務層,Controller層。

  N個模塊,N*M個服務

RPC框架、服務註冊與發現中心:

  索引和指南

  在大量的信息中,查詢須要的信息

負載均衡:

  nginx

  統一的入口地址:獲取信息的入口

  信息多,信息請求多=》負載均衡,將準確的信息給須要的人

  所在的網絡:

    是一個世界知名的地址,稱爲外網IP地址,這個地址是全球可定位的

    經過NAT規則,將外網IP地址,變成內網的私有IP地址

 BGP協議:Border Gateway Protocol,邊界網關協議

  對於多個可用區的狀況,咱們能夠隱去計算節點的狀況,將外網訪問區域放大

外網IP是放在虛擬網關的外網網口上的,這個IP如何讓全世界知道呢?

  在覈心交換外面是安全設備,而後就是邊界路由器。

    邊界路由器會和多個運營商鏈接,從而每一個運營商都可以訪問到這個網站。

    邊界路由器能夠經過BGP協議,將本身數據中內心面的外網IP向外廣播,也就是告訴全世界,若是要訪問這些外網IP,都來我這裏。

  每一個運營商也有不少的路由器、不少的點,因而就能夠將如何到達這些IP地址的路由信息,廣播到全國乃至全世界。

 

 

CDN模式:Content Delivery Network,內容分發網絡

  是構建在網絡之上的內容分發網絡,依靠部署在各地的邊緣服務器,經過中心平臺的負載均衡、內容分發、調度等功能模塊,使用戶就近獲取所需內容,下降網絡擁塞,提升用戶訪問響應速度和命中率

  關鍵技術主要有內容存儲和分發技術

 

 部署應用的時候,通常會把靜態資源保存在兩個地方(這兩個地方的靜態資源都會配置CDN,將資源下發到邊緣節點)

  一個是nginx後面的varnish緩存裏面,通常是靜態頁面

   對於比較大的、不常常更新的靜態圖片,會保存在對象存儲裏面

 

配置了CDN以後,權威DNS服務器上,會爲靜態資源設置一個CNAME別名,指向另一個域名cdn.com,返回給本地DNS服務器。

當本地DNS服務器拿到這個新的域名時,須要繼續解析這個新的域名。

  這個時候,再訪問的時候就不是原來的權威DNS服務器了,而是 cdn.com 的權威DNS服務器。

    這是CDN本身的權威DNS服務器。

    在這個服務器上,仍是會設置一個CNAME,指向另一個域名,也即CDN網絡的全局負載均衡器。

本地DNS服務器去請求CDN的全局負載均衡器解析域名,全局負載均衡器會爲用戶選擇一臺合適的緩存服務器提供服務,將IP返回給客戶端,客戶端去訪問這個邊緣節點,下載資源。

  緩存服務器響應用戶請求,將用戶所需內容傳送到用戶終端。

  若是這臺緩存服務器上並無用戶想要的內容,那麼這臺服務器就要向它的上一級緩存服務器請求內容,直至追溯到網站的源服務器,將內容拉到本地。

  CDN的全局負載均衡策略:就近獲取緩存數據(可能存在時延,數據不是最新的 =》回源)

    例如:就至關於當僧人們想讀佛經的時候,沒必要要都去西天,而是能夠就近去問,周圍有沒有廟宇,而後向廟宇的師傅去請教佛經。

    然而緩存的佛經固然是比不上西天取到的經文更新,因此東土因爲離西天較遠,緩存的仍是小乘佛教,要讀大乘佛教,就要去西天取經,稱爲回源。

 

DNS解析:知道目標,找到到達目標的路徑

  當在手機上面打開一個App的時候,首先要作的事情就是解析這個網站的域名。

    在手機運營商所在的互聯網區域裏,有一個本地的DNS,手機會向這個DNS請求解析DNS。

      當這個DNS本地有緩存,則直接返回;

      若是沒有緩存,本地DNS才須要遞歸地從根DNS服務器,查到.com的頂級域名服務器,最終查到權威DNS服務器

  若是你使用雲平臺的時候,配置了智能DNS和全局負載均衡,

    在權威DNS服務中,通常是經過配置CNAME的方式,咱們能夠起一個別名,例如 vip.yourcomany.com ,

      而後告訴本地DNS服務器,讓它請求GSLB解析這個域名,GSLB就能夠在解析這個域名的過程當中,經過本身的策略實現負載均衡。

    GSLB經過查看請求它的本地DNS服務器所在的運營商和地址,就知道用戶所在的運營商和地址,

      而後將距離用戶位置比較近的Region裏面,將三個本地負載均衡的公網IP地址,返回給本地DNS服務器。

    本地DNS解析器將結果緩存後,返回給客戶端。

  對於手機APP來講,能夠繞過剛纔的傳統DNS解析機制,直接只要HTTPDNS服務,

    經過直接調用HTTPDNS服務器,獲得這三個本地負載均衡的公網IP地址。

 

 

客戶端證書:證實客戶端的合法性

客戶端對服務端發起請求:

  應用層請求

  應用層之下的TCP:防止公網的丟包

  請求是應用層的,發起的是HTTP的協議,在HTTP的請求正文中,寫的請求的具體信息

 

TCP層的,TCP是面向鏈接的,TCP 是靠譜的協議,可是這不能說明它面臨的網絡環境好。

  從 IP 層面來說,若是網絡情況的確那麼差,是沒有任何可靠性保證的,

  而做爲 IP 的上一層 TCP 也無能爲力,惟一能作的就是更加努力,不斷重傳,經過各類算法保證。(一旦丟包,不斷重試)

    也就是說,對於 TCP 來說,IP 層你丟不丟包,我管不着,可是我在個人層面上,會努力保證可靠性。

    爲了可以實現重試,實現TCP的可靠性,客戶端和服務器須要創建鏈接。

 

 HTTPS協議是基於TCP協議的,於是要先創建TCP的鏈接

  在這個例子中,TCP的鏈接是從手機上的App和負載均衡器SLB之間的。也就是唐僧和金頂大仙之間,到了金頂大仙,就不怕了,會指引到佛祖那裏的。

  儘管中間要通過不少的路由器和交換機,可是TCP的鏈接是端到端的。

    TCP這一層和更上層的HTTPS沒法看到中間的包的過程。

    儘管創建鏈接的時候,全部的包都逃不過在這些路由器和交換機之間的轉發,轉發的細節咱們放到那個下單請求的發送過程當中詳細解讀,這裏只看端到端的行爲。

  對於TCP鏈接來說,須要經過三次握手創建鏈接,爲了維護這個鏈接,雙方都須要在TCP層維護一個鏈接的狀態機。

    一開始,客戶端和服務端都處於CLOSED狀態。服務端先是主動監聽某個端口,處於LISTEN狀態。而後客戶端主動發起鏈接SYN,以後處於SYN-SENT狀態。

    服務端收到發起的鏈接,返回SYN,而且ACK客戶端的SYN,以後處於SYN-RCVD狀態。

    客戶端收到服務端發送的SYN和ACK以後,發送ACK的ACK,以後處於ESTABLISHED狀態。這是由於,它一發一收成功了。服務端收到ACK的ACK以後,處於ESTABLISHED狀態,由於它的一發一收也成功了。

 

當TCP層的鏈接創建完畢以後,接下來輪到HTTPS層創建鏈接了,在HTTPS的交換過程當中,TCP層始終處於ESTABLISHED。

  對於HTTPS,客戶端會發送Client Hello消息到服務器,

    用明文傳輸TLS版本信息、加密套件候選列表、壓縮算法候選列表等信息。

    另外,還會有一個隨機數,在協商對稱密鑰的時候使用。

  而後,服務器會返回Server Hello消息,

    告訴客戶端,服務器選擇使用的協議版本、加密套件、壓縮算法等。

    這也有一個隨機數,用於後續的密鑰協商。

  而後,服務器會給你一個服務器端的證書,而後說:「Server Hello Done,我這裏就這些信息了。」

  客戶端固然不相信這個證書,因而你從本身信任的CA倉庫中,拿CA的證書裏面的公鑰去解密電商網站的證書。

    若是可以成功,則說明電商網站是可信的。這個過程當中,你可能會不斷往上追溯CA、CA的CA、CA的CA的CA,反正直到一個授信的CA,就能夠了。

    CA:向客戶端證實服務器端的可信性

      防止:數據包被截獲=》帶着客戶端證書假裝一個請求

  證書驗證完畢以後,以爲這個服務端是可信的,因而客戶端計算產生隨機數字Pre-master,發送Client Key Exchange,

    用證書中的公鑰加密,再發送給服務器,服務器能夠經過私鑰解密出來。

  接下來,不管是客戶端仍是服務器,都有了三個隨機數,分別是:本身的、對端的,以及剛生成的Pre-Master隨機數。

    經過這三個隨機數,能夠在客戶端和服務器產生相同的對稱密鑰。

    有了對稱密鑰,客戶端就能夠說:「Change Cipher Spec,我們之後都採用協商的通訊密鑰和加密算法進行加密通訊了。」

      而後客戶端發送一個Encrypted Handshake Message,將已經商定好的參數等,採用協商密鑰進行加密,發送給服務器用於數據與握手驗證。

      一樣,服務器也能夠發送Change Cipher Spec,說:「沒問題,我們之後都採用協商的通訊密鑰和加密算法進行加密通訊了」,而且也發送Encrypted Handshake Message的消息試試。

  當雙方握手結束以後,就能夠經過對稱密鑰進行加密傳輸了。

 

舉例:

  應用層:唐太宗,關注保大唐江山永固,

  TCP層||網絡包:玄奘,經過堅決的意志到達西天

  IP層:李世民給的通關文牒,未來要經過這個文牒經過一個個城關

  MAC層:李世民給的金鉢盂,這個用於玄奘法師到了某個城市裏面化齋,同時打聽路的時候使用

  物理層:李世民給的白馬一匹,做爲遠程腳力

 

當客戶端和服務端之間創建了鏈接後,接下來就要發送下單請求的網絡包了。

  在用戶層發送的是HTTP的網絡包,由於服務端提供的是RESTful API,於是HTTP層發送的就是一個請求。

    HTTP的報文大概分爲三大部分。

      第一部分是請求行:

        URL就是 www.geektime.com/purchaseOrder ,

        版本爲HTTP 1.1。

        請求的類型叫做POST,它須要主動告訴服務端一些信息,而非獲取。須要告訴服務端什麼呢?通常會放在正文裏面。正文能夠有各類各樣的格式,常見的格式是JSON。

      第二部分是請求的首部

        首部是key value,經過冒號分隔

        Content-Type是指正文的格式。例如,咱們進行POST的請求,若是正文是JSON,那麼咱們就應該將這個值設置爲JSON。

      第三部分纔是請求的正文實體

        這裏是一個JSON字符串,裏面經過文本的形式描述了,要買一個課程,做者是誰,多少錢。

POST /purchaseOrder HTTP/1.1
Host: www.geektime.com
Content-Type: application/json; charset=utf-8
Content-Length: nnn
 
{
 "order": {
  "date": "2018-07-01",
  "className": "趣談網絡協議",
  "Author": "劉超",
  "price": "68"
 }
}

    

  HTTP請求的報文格式就拼湊好了。接下來瀏覽器或者移動App會把它交給下一層傳輸層。

    怎麼交給傳輸層呢?也是用Socket進行程序設計。

      若是用的是瀏覽器,這些程序不須要你本身寫,有人已經幫你寫好了;

      若是在移動APP裏面,通常會用一個HTTP的客戶端工具來發送,而且幫你封裝好。

  HTTP協議是基於TCP協議的,因此它使用面向鏈接的方式發送請求,經過Stream二進制流的方式傳給對方。

    固然,到了TCP層,它會把二進制流變成一個的報文段發送給服務器。

    在TCP頭裏面,會有源端口號和目標端口號,

      目標端口號通常是服務端監聽的端口號,

      源端口號在手機端,每每是隨機分配一個端口號。

      這個端口號在客戶端和服務端用於區分請求和返回,發給那個應用。

    在IP頭裏面,都須要加上本身的地址(即源地址)和它想要去的地方(即目標地址)。

      當一個手機上線的時候,PGW會給這個手機分配一個IP地址,這就是源地址,

      而目標地址則是雲平臺的負載均衡器的外網IP地址。

    在IP層,客戶端須要查看目標地址和本身是不是在同一個局域網,計算是不是同一個網段,每每須要經過CIDR子網掩碼來計算。

      對於這個下單場景,目標IP和源IP不會在同一個網段,於是須要發送到默認的網關。通常經過DHCP分配IP地址的時候,也會同時配置默認網關的IP地址。

      可是客戶端不會直接使用默認網關的IP地址,而是發送ARP協議,來獲取網關的MAC地址,而後將網關MAC做爲目標MAC,本身的MAC做爲源MAC,放入MAC頭,發送出去。

一個完整的網絡包的格式:

網絡包就正式發出了。

  若是你是用手機打開APP,下單購物發送網絡包,通常經過手機運營商的網絡。

    客戶的手機開機之後,在附近尋找基站eNodeB,發送請求,申請上網。

    基站將請求發給MME,MME對手機進行認證和鑑權,還會請求HSS看有沒有錢,看看是在哪裏上網。

    當MME經過了手機的認證以後,開始創建隧道,建設的數據通路分兩段路,實際上是兩個隧道。

      一段是從eNodeB到SGW,

      第二段是從SGW到PGW,

      在PGW以外,就是互聯網。

    PGW會爲手機分配一個IP地址,手機上網都是帶着這個IP地址的。

      對於手機來說,默認的網關在PGW上。

      在移動網絡裏面,從手機到SGW,到PGW是有一條隧道的。

        在這條隧道里面,會將上面的這個包做爲隧道的乘客協議放在裏面,外面SGW和PGW在覈心網機房的IP地址。

        網絡包直到PGW(PGW是隧道的另外一端)纔將裏面的包解出來,轉發到外部網絡。

    因此,從手機發送出來的時候,網絡包的結構爲:

    • 源MAC:手機也即UE的MAC;
    • 目標MAC:網關PGW上面的隧道端點的MAC;
    • 源IP:UE的IP地址;
    • 目標IP:SLB的公網IP地址

    進入隧道以後,要封裝外層的網絡地址,於是網絡包的格式爲:

    • 外層源MAC:E-NodeB的MAC;
    • 外層目標MAC:SGW的MAC;
    • 外層源IP:E-NodeB的IP;
    • 外層目標IP:SGW的IP;
    • 內層源MAC:手機也即UE的MAC;
    • 內層目標MAC:網關PGW上面的隧道端點的MAC;
    • 內層源IP:UE的IP地址;
    • 內層目標IP:SLB的公網IP地址。

    當隧道在SGW的時候,切換了一個隧道,爲從SGW到PGW的隧道,於是網絡包的格式爲:

    • 外層源MAC:SGW的MAC;
    • 外層目標MAC:PGW的MAC;
    • 外層源IP:SGW的IP;
    • 外層目標IP:PGW的IP;
    • 內層源MAC:手機也即UE的MAC;
    • 內層目標MAC:網關PGW上面的隧道端點的MAC;
    • 內層源IP:UE的IP地址;
    • 內層目標IP:SLB的公網IP地址。

    在PGW的隧道端點將包解出來,轉發出去的時候,

      通常在PGW出外部網絡的路由器上,會部署NAT服務,將手機的IP地址轉換爲公網IP地址,當請求返回的時候,再NAT回來。

      於是在PGW以後,至關於作了一次歐洲十國遊型的轉發,網絡包的格式爲:

    • 源MAC:PGW出口的MAC;
    • 目標MAC:NAT網關的MAC;
    • 源IP:UE的IP地址;
    • 目標IP:SLB的公網IP地址。

    在NAT網關,至關於作了一次玄奘西遊型的轉發,網絡包的格式變成:

    • 源MAC:NAT網關的MAC;
    • 目標MAC:A2路由器的MAC;
    • 源IP:UE的公網IP地址;
    • 目標IP:SLB的公網IP地址。

    在手機運營商的網絡裏面,網絡情況是比較好的。

 

 

NAT:Network Address Translation,網絡地址轉換

到達邊界路由器=>開始NAT=>使用公網IP

 

路由問題:

  內網如何到達?

    主要遵循最短路徑原則,就是走得路越少越好,道路越短越好

      在大學裏面學習計算機網絡與數據結構的時候,知道求最短路徑經常使用的有兩種方法,一種是 Bellman-Ford 算法,一種是 Dijkstra 算法。在計算機網絡中基本也是用這兩種方法計算的。

      距離矢量路由(distance vector routing),它是基於 Bellman-Ford 算法的。

      鏈路狀態路由(link state routing),基於 Dijkstra 算法。

  網外如何到達?

    不但要考慮遠近的問題,還要考慮政策的問題

      例若有的國家路近,可是路過的國家看不慣僧人,見了僧人就抓。例如滅法國,連光頭都要抓。這樣的狀況即使路近,也最好繞遠點走。

  

  最經常使用的兩種路由協議:

    OSPF(Open Shortest Path First,開放式最短路徑優先)

      一個基於鏈路狀態路由協議,普遍應用在數據中心中的協議,

      稱爲內部網關協議(Interior Gateway Protocol,簡稱IGP)

    BGP 協議

      使用的算法是路徑矢量路由協議(path-vector protocol)。它是距離矢量路由協議的升級版,

      稱爲外網路由協議(Border Gateway Protocol,簡稱BGP)

 

路由協議是城關之間相互溝通到哪裏應該怎麼走的協議。

IP協議:解決如何問路的問題

  例如:靠通關文牒了,裏面寫着貧僧來自東土大唐(就是源IP地址),欲往西天拜佛求經(指的是目標IP地址)。路過寶地,借宿一晚,明日啓行,請問接下來該怎麼走啊?(中轉,詢問路由)

     在解決第一個問題的時候,每一個城關已經經過菩薩的法術,和鄰近的城關進行溝通,知道了下面的信息。

    路由表:根據這個表格,能夠告訴唐僧怎麼走

    

  

 

SLB: Server Load Balancing,服務器負載均衡

出了NAT網關,就從核心網到達了互聯網。

  在網絡世界,每個運營商的網絡成爲自治系統AS。

  每一個自治系統都有邊界路由器,經過它和外面的世界創建聯繫。

對於雲平臺來說,它能夠被稱爲Multihomed AS,有多個鏈接連到其餘的AS,可是大多拒絕幫其餘的AS傳輸包。

  例如一些大公司的網絡。

對於運營商來講,它能夠被稱爲Transit AS,有多個鏈接連到其餘的AS,而且能夠幫助其餘的AS傳輸包,

  好比主幹網。

如何從出口的運營商到達雲平臺的邊界路由器?

  在路由器之間須要經過BGP協議實現,

    BGP又分爲兩類,eBGP和iBGP。

  自治系統間,邊界路由器之間使用eBGP廣播路由。

    內部網絡也須要訪問其餘的自治系統。

  邊界路由器如何將BGP學習到的路由導入到內部網絡呢?

    經過運行iBGP,使內部的路由器可以找到到達外網目的地最好的邊界路由器。

網站的SLB的公網IP地址早已經經過雲平臺的邊界路由器,讓全網都知道了。

  因而這個下單的網絡包選擇了下一跳是A2,也即將A2的MAC地址放在目標MAC地址中。

  到達A2以後,從路由表中找到下一跳是路由器C1,因而將目標MAC換成C1的MAC地址。

  到達C1以後,找到下一跳是C2,將目標MAC地址設置爲C2的MAC。

  到達C2後,找到下一跳是雲平臺的邊界路由器,因而將目標MAC設置爲邊界路由器的MAC地址。

  你會發現,這一路,都是隻換MAC,不換目標IP地址。這就是所謂下一跳的概念。

  在雲平臺的邊界路由器,會將下單的包轉發進來,

    通過核心交換,匯聚交換,到達外網網關節點上的SLB的公網IP地址。

咱們能夠看到,手機到SLB的公網IP,是一個端到端的鏈接,鏈接的過程發送了不少包。

  全部這些包,不管是TCP三次握手,仍是HTTPS的密鑰交換,都是要走如此複雜的過程到達SLB的,固然每一個包走的路徑不必定一致。

  當網絡包走在這個複雜的道路上,極可能一不當心就丟了,怎麼辦?

    這就須要藉助TCP的機制從新發送。

      既然TCP要對包進行重傳,就須要維護一個Sequence Number,看哪些包到了,哪些沒到,哪些須要重傳,傳輸的速度應該控制到多少,這就是TCP的滑動窗口協議

整個TCP的發送,一開始會協商一個Sequence Number,從這個Sequence Number開始,每一個包都有編號。

滑動窗口將接收方的網絡包分紅四個部分:

  • 已經接收,已經ACK,已經交給應用層的包;
  • 已經接收,已經ACK,未發送給應用層;
  • 已經接收,還沒有發送ACK;
  • 未接收,尚有空閒的緩存區域。

 對於TCP層來說,每個包都有ACK。

  ACK須要從SLB回覆到手機端,將上面的那個過程反向來一遍,固然路徑不必定一致,可見ACK也不是那麼輕鬆的事情

若是發送方超過必定的時間沒有收到ACK,就會從新發送。

  只有TCP層ACK過的包,纔會發給應用層,而且只會發送一份,對於下單的場景,應用層是HTTP層。

你可能會問了,TCP總是重複發送,會不會致使一個單下了兩遍?是否要求服務端實現冪?

  從TCP的機制來看,是不會的。

  只有收不到ACK的包纔會重複發,發到接收端,在窗口裏面只保存一份,因此在同一個TCP鏈接中,不用擔憂重傳致使二次下單。

    可是TCP鏈接會由於某種緣由斷了,例如手機信號很差,這個時候手機把全部的動做從新作一遍,創建一個新的TCP鏈接,在HTTP層調用兩次RESTful API。

    這個時候可能會致使兩遍下單的狀況,於是RESTful API須要實現冪等。

 當ACK過的包發給應用層以後,TCP層的緩存就空了出來,

  這會致使上面圖中的大三角,也即接收方可以容納的總緩存,總體順時針滑動。

  小的三角形,也即接收方告知發送方的窗口總大小,也即尚未徹底確認收到的緩存大小,若是把這些填滿了,就不能再發了,由於沒確認收到,因此一個都不能扔。

 

 

 負載均衡

網絡包從手機端經歷千難萬險,終於到了SLB的公網IP所在的公網網口。

  因爲匹配上了MAC地址和IP地址,於是將網絡包收了進來。

 

NAT爲內網IP

  在虛擬網關節點的外網網口上,會有一個NAT規則,將公網IP地址轉換爲VPC裏面的私網IP地址,

    這個私網IP地址就是SLB的HAProxy所在的虛擬機的私網IP地址

    從而網絡包也脫胎換骨,實現公網IP到私有網絡IP的轉換。

 

 

 

爲了承載比較大的吞吐量,虛擬網關節點會有多個,

  物理網絡會將流量分發到不一樣的虛擬網關節點。

一樣HAProxy也會是一個大的集羣,

  虛擬網關會選擇某個負載均衡節點,將某個請求分發給它,

  負載均衡以後是Controller層,也是部署在虛擬機裏面的。

當網絡包裏面的目標IP變成私有IP地址地址以後,虛擬路由會查找路由規則,將網絡包從下方的私網網口發出來。這個時候包的格式爲:

  • 源MAC:網關MAC;
  • 目標MAC:HAProxy虛擬機的MAC;
  • 源IP:UE的公網IP;
  • 目標IP:HAProxy虛擬機的私網IP。

 

在虛擬路由節點上,也會有OVS,將網絡包封裝在VXLAN隧道里面,VXLAN ID就是給你的租戶建立VPC的時候分配的。

  VXLAN ID就是VPC虛擬空間的ID,

  OVS就是那個可以封裝和解開私密空間的法寶。

  例如:在第一部分,咱們 說佛經是存放在一個虛擬空間裏面的,要打開這個虛擬空間,解讀經文,須要一個芝麻開門的ID。接引佛祖會給玄奘法師一個ID。

  包的格式爲:

    • 外層源MAC:網關物理機MAC;
    • 外層目標MAC:物理機A的MAC;
    • 外層源IP:網關物理機IP;
    • 外層目標IP:物理機A的IP;
    • 內層源MAC:網關MAC;
    • 內層目標MAC:HAProxy虛擬機的MAC;
    • 內層源IP:UE的公網IP;
    • 內層目標IP:HAProxy虛擬機的私網IP。

  在物理機A上,OVS會將包從VXLAN隧道里面解出來,發給HAProxy所在的虛擬機。

    HAProxy所在的虛擬機發現MAC地址匹配,目標IP地址匹配,就根據TCP端口,將包發給HAProxy進程,由於HAProxy是在監聽這個TCP端口的。

    於是HAProxy就是這個TCP鏈接的服務端,客戶端是手機。對於TCP的鏈接狀態,滑動窗口等,都是在HAProxy上維護的。

  在這裏HAProxy是一個四層負載均衡,也即他只解析到TCP層,裏面的HTTP協議他不關心,

    就將請求轉發給後端的多個Controller層的一個。

    HAProxy發出去的網絡包就認爲HAProxy是客戶端了,看不到手機端了。網絡包格式以下:

    • 源MAC:HAProxy所在虛擬機的MAC;
    • 目標MAC:Controller層所在虛擬機的MAC;
    • 源IP:HAProxy所在虛擬機的私網IP;
    • 目標IP:Controller層所在虛擬機的私網IP。

    固然這個包發出去以後,仍是會被物理機上的OVS放入VXLAN隧道里面,網絡包格式爲: 

    • 外層源MAC:物理機A的MAC;
    • 外層目標MAC:物理機B的MAC;
    • 外層源IP:物理機A的IP;
    • 外層目標IP:物理機B的IP;
    • 內層源MAC:HAProxy所在虛擬機的MAC;
    • 內層目標MAC:Controller層所在虛擬機的MAC;
    • 內層源IP:HAProxy所在虛擬機的私網IP;
    • 內層目標IP:Controller層所在虛擬機的私網IP。

    在物理機B上,OVS會將包從VXLAN隧道里面解出來,發給Controller層所在的虛擬機。

      Controller層所在的虛擬機發現MAC地址匹配,目標IP地址匹配,就根據TCP端口,將包發給Controller層的進程,由於他是在監聽這個TCP端口的。

    在HAProxy和Controller層之間,維護一個TCP的鏈接。

      Controller層收到包以後,他是關心HTTP裏面是什麼的,因而解開HTTP的包,發現是一個POST請求,內容是下單購買一個課程。

 

請求到達服務端Controller層

  RPC協議:

    在電商服務裏面,每每在組合服務層會有一個專門管理下單的服務,

    Controller層雖然對外暴露的是標準的RESTful協議,可是對內會經過RPC協議(若是不懂這個協議,就無法通訊)調用這個組合服務層

    假設咱們使用的是Dubbo,則Controller層須要讀取註冊中心,將下單服務的進程列表拿出來,選出一個來調用

      Dubbo中默認的RPC協議是Hessian2。Hessian2將下單的遠程調用序列化爲二進制進行傳輸。

      Netty是一個非阻塞的基於事件的網絡傳輸框架。Controller層和下單服務之間,使用了Netty的網絡傳輸框架。

        有了Netty,就不用本身編寫複雜的異步Socket程序了。

        Netty使用的方式,就是我們講Socket編程的時候,一個項目組支撐多個項目(IO多路複用,從派人盯着到有事通知)這種方式。

        Netty仍是工做在Socket這一層的,發送的網絡包仍是基於TCP的。在TCP的下層,仍是須要封裝上IP頭和MAC頭。

          若是跨物理機通訊,仍是須要封裝的外層的VXLAN隧道里面。固然底層的這些封裝,Netty都不感知,它只要作好它的異步通訊便可。

        在Netty的服務端,也即下單服務中,

          收到請求後,先用Hessian2的格式進行解壓縮。

          而後將請求分發到線程中進行處理,在線程中,會調用下單的業務邏輯。

    

  懂得內情的註冊中心ZK:

    容錯:服務器請求出錯

    找到門路:懂得服務方的規矩

    .proto文件

 

下單的業務邏輯比較複雜,每每要調用基礎服務層裏面的庫存服務、優惠券服務等,將多個服務調用完畢,纔算下單成功。

  下單服務調用庫存服務和優惠券服務,也是經過Dubbo的框架,經過註冊中心拿到庫存服務和優惠券服務的列表,而後選一個調用。

  調用的時候,統一使用Hessian2進行序列化,使用Netty進行傳輸,底層若是跨物理機,仍然須要經過VXLAN的封裝和解封裝。

  以庫存爲例子的時候,講述過冪等的接口實現的問題。

    由於若是扣減庫存,僅僅是誰調用誰減一。這樣存在的問題是,若是扣減庫存由於一次調用失敗,而屢次調用,這裏指的不是TCP屢次重試,而是應用層調用的屢次重試,就會存在庫存扣減屢次的狀況。

    這裏經常使用的方法是,使用樂觀鎖(Compare and Set,簡稱CAS)。

      CAS要考慮三個方面,當前的庫存數、預期原來的庫存數和版本,以及新的庫存數。

      在操做以前,查詢出原來的庫存數和版本,真正扣減庫存的時候,判斷若是當前庫存的值與預期原值和版本相匹配,則將庫存值更新爲新值,不然不作任何操做。

      這是一種基於狀態而非基於動做的設計,符合REST的架構設計原則。這樣的設計有利於高併發場景。

        當多個線程嘗試使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值,而其它線程都失敗,失敗的線程並不會被掛起,而是被告知此次競爭中失敗,並能夠再次嘗試。

  最終,當下單更新到分佈式數據庫中以後,整個下單過程纔算真正告一段落。

    固然,這個下單調用要返回一個結果:咱們下單成功啦!!!!!!

相關文章
相關標籤/搜索