《Go語言網絡編程》第一章:體系

原書地址:http://tumregels.github.io/Network-Programming-with-Go前端

若是不知道想要構建什麼,是不可能建立一個系統的。並且若是不知道它工做的環境,也一樣沒法構建。git

GUI程序不一樣於批處理程序;遊戲程序不一樣於商業程序;分佈式程序不一樣於單機程序。程序員

他們都有本身的方法、通常模式和問題,都有各自的常見問題和常看法決方案。github

本章討論分佈式系統高層架構層面的一些內容。有多種方式看待這樣的系統,並且其中的許多問題已經被解決。數據庫

協議層

分佈式系統很難!其中涉及到多臺計算機,他們必須以某種方式進行鏈接。編寫的程序必須在系統中每臺計算機都能正常運行,而且他們必須通力協做才能完成分佈式任務。編程

處理複雜性問題的經常使用方法是將其劃分紅一個個更小更簡單的分塊兒。這些一個個分塊兒有本身的結構,但它們也定義了與其餘相關分塊兒通訊的方法。在分佈式系統中,這些分塊兒稱爲協議層,他們具備明肯定義的功能。全部的分塊兒組成了一個棧,每一層只同本身的上一層和下一層進行通訊。各層之間的通訊由協議定義。後端

網絡通訊要求協議涵蓋從高級應用程序通訊到金屬導線通訊的全部通訊,而且經過協議層封裝處理其中的複雜性。瀏覽器

ISO OSI協議

儘管歷來沒有真正實現,在分佈式系統設計的討論和影響方面OSI(Open Systems Interconnect,開放式系統互聯)協議一直是主要的影響因素。該協議一般以下圖所示:安全

OSI協議層

每一層的功能:服務器

  • 網絡層提供交換和路由技術
  • 傳輸層在終端系統之間提供透明的數據傳輸,負責端到端錯誤恢復和流控制
  • 會話層創建、管理和終止應用程序之間的鏈接。
  • 表示層提供獨立於數據表示的差別(例如加密)
  • 應用層支持應用程序和最終用戶進程

TCP/IP協議

在OSI模型被爭論、辯論、爭奪時,DARPA互聯網研究項目正在忙於構建TCP / IP協議,並取得了巨大的成功,且挾裹資本帶來了互聯網。這是一個簡單得多的協議棧:

一些替代協議

雖然它看起來TCP/IP已經一統天下,但TCP / IP協議並非惟一存在的協議,從長遠來看可能甚至不是最成功的協議。 有許多協議佔據重要的位置,例如:

  • 火線(Firewire)
  • USB(Universal Serial Bus,通用串行總線)
  • 藍牙(Bluetooth)
  • WiFi(Wireless Fidelity,基於IEEE 802.11b標準的無線局域網)

許多其餘協議的工做仍在積極進行,甚至是一些很是奇怪的協議,如「太空互聯網」協議。

本書的重點是TCP / IP,但你應該知道是有其餘協議存在的。

網絡

網絡是一種用於鏈接主機終端系統的通訊系統。鏈接載體能夠是銅線、以太網、光纖或無線電磁波,但這些與咱們無關。局域網( LAN )將距離較近的計算機鏈接在一塊兒,這些計算機一般屬於家庭、小型組織或大型組織的一部分。廣域網(WAN)將更大物理區域的計算機鏈接在一塊兒,例如城市之間。還有一些其餘類型網絡,如城域網、我的區域網,甚至是身體區域網。

互聯網是兩個或更多不一樣網絡的鏈接,一般是局域網或廣域網。內部網是全部網絡都屬於一個組織的互聯網。

因特網和內部網之間有很大的區別。一般內部網將處於單一的管理控制之下,這將強加一套統一的策略。另外一方面,互聯網不受單一機構的控制,對不一樣部分的控制甚至可能不兼容。

這種差別的一個例子是,內部網一般會被少數供應商限制運行特定操做系統標準化版本的計算機上。另外一方面,互聯網中一般會是不一樣計算機和操做系統的大雜燴。

本書的技術將適用於互聯網。它們對內部網也是有效的,可是在內部網中你還能碰到專用的不可移植系統。

而後是全部互聯網(internet)的「母親」:因特網/互聯網(譯註:The Internet,注意,在英文中加定冠詞The且首字母大寫特指i因特網,也就是中國大陸普稱的互聯網。中國臺灣所稱的網路,而internet表示互聯網這一類網絡。)。這是一個很是很是大的互聯網,它把咱們鏈接到谷歌,把個人電腦鏈接到你的電腦,等等。

網關

網關是用於鏈接兩個或多個網絡的實體的通用術語。中繼器在物理層面上工做,將信息從一個子網複製到另外一個子網。網橋在數據鏈路層運行,並在網絡之間複製幀。路由器在網絡層上運行,不只在網絡之間傳輸信息,並且選取決定路由

數據包封裝

不管OSI仍是TCP/IP堆棧,其各層之間的通訊是經過將數據包從一層發送到下一層,而後最終經過網絡完成的。每一層都有關於它本身的層的管理信息。 在發送端,當數據包向下傳遞時,它經過將報頭信息添加到從上面的層接收到的數據包中來實現這一點。 在接收端,隨着數據包的向上移動,這些報頭會被刪除。(譯註:發送時就像是一層層的包洋蔥,接收時就像一層層剝洋蔥)。

例如,TFTP(Trivial File Transfer Protocol,簡單文件傳輸協議)將文件從一臺計算機移動到另外一臺計算機。它使用IP協議之上的UDP協議,IP協議能夠經過以太網發送。這看起來像:

經過以太網傳輸的數據包固然是最下層的那個。

鏈接模型

爲了讓兩臺計算機通訊,它們必須設置一條路徑,以便在一個會話中至少發送一條消息。這有兩種主要模式:

  • 面向鏈接
  • 無鏈接

面向鏈接

會爲會話創建單個鏈接。沿着鏈接的雙向通訊流(譯註:雙工通訊),會話結束時,鏈接斷開。這相似於電話交談,TCP就是一個例子。

無鏈接

在無鏈接系統中,消息彼此獨立地發送。普通郵件就是一個例子。無鏈接消息可能會無序到達。一個例子是IP協議。

面向鏈接的傳輸能夠創建在無鏈接的傳輸之上——IP上的TCP。無鏈接傳輸能夠創建在面向鏈接的傳輸之上——基於TCP的HTTP。

這也有一些有所不一樣。例如,會話可能強制消息到達,但可能不能保證它們按照發送的順序到達。然而,這兩個是最多見的。

通訊模型

消息傳遞

一些非過程性語言是基於消息傳遞原則構建的。併發語言常用這種機制,最著名的例子多是Unix管道。Unix管道是一個字節管道,但沒有固有的限制:微軟的PowerShell能夠沿其管道發送對象,Parlog等併發語言能夠在併發進程之間的消息中發送任意邏輯數據結構。

消息傳遞是分佈式系統的一種基本機制。 創建鏈接並向其輸送一些數據。 在另外一端,弄清楚消息是什麼並對其作出響應,可能會發回消息。 以下圖所示:

低層事件驅動系統,如X窗口系統,以與此種相似的方式運行:等待來自用戶的消息(鼠標單擊等),對其進行解碼並對其進行操做。

更高級別的事件驅動系統假設這個解碼已經由底層系統完成,而後事件被分派到一個適當的對象,好比ButtonPress handler。這也能夠在分佈式消息傳遞系統中完成,由此經過網絡接收到的消息被部分解碼並分派給適當的handler。

遠程過程調用

在任何系統中,都有信息和流量控制從系統的一部分轉移到另外一部分。在面向過程的語言中,這可能包括過程調用,其中信息被放置在調用堆棧中,而後控制流被轉移到程序的另外一部分。

即便使用過程調用,也會有一些變化。 爲了控制從程序可執行代碼的一部分轉移到另外一部分。代碼有多是靜態連接的。因爲愈來愈多地使用庫例程,在控制權轉移到獨立的代碼段動態連接庫( DLL-s )中擁有這樣的代碼已經變得司空見慣。

DLLs與調用代碼在同一臺機器上運行。將控制轉移到另外一臺機器上運行的過程在概念上是一個簡單的步驟。然而這其中的機制並不簡單!這種控制模型驅動了「遠程過程調用」(RPC),這將在後面的章節中詳細討論。如圖所示:

微軟在從16位應用程序到32位應用程序的轉換過程當中發明了一種名爲「輕量級遠程過程調用」的歷史怪物。16位應用程序可能須要將數據傳輸到同一臺計算機上的32位應用程序。因爲沒有網絡,這使得它很是輕巧!可是在數據表示和轉換方面,它還有許多RPC系統的其餘問題。

分佈式計算模型

在最高層,咱們能夠考慮分佈式系統組件的等價性或不等價性。最多見的狀況是不對稱的:客戶機向服務器發送請求,服務器做出響應。這是一個C/S系統。

若是兩個組件都是等效的,都可以啓動和響應消息,那麼咱們就有了一個點對點系統(peer-to-peer,p2pm對等系統)。請注意,這是一個邏輯分類:一個對等點多是16000核心主機,另外一個多是移動電話。但若是他們都能作出相似的行爲,那麼他們就是對等的。

第三種模型是所謂的過濾器。在這裏,一個組件將信息傳遞給另外一個組件,後者在將信息傳遞給第三個組件以前對其進行修改。這是一種至關常見的模型:例如,中間組件以SQL記錄的形式從數據庫獲取信息,並將其轉換爲第三個組件(多是瀏覽器)的HTML表。

C/S系統

客戶端/服務器系統的另外一個觀點是:

C/S應用

第三種觀點是:

服務器組織分佈

C/S系統並不簡單。基本模型是單客戶機、單服務器:

可是你也能夠有多個客戶端,單個服務器:

在這種狀況下,主服務器接收請求以後將它們傳遞給其餘服務器來處理,而不是一次處理一個請求。當客戶端是能夠併發時,這是一種常見的模型。

還有單個客戶機和多個服務器:

當服務器須要充當其餘服務器的客戶端時,這種狀況常常發生,例如業務邏輯服務器從數據庫服務器獲取信息。

固然,也能夠有多個客戶機和多個服務器。

組件組織分佈

分解許多應用程序的一種簡單但有效的方法是將它們視爲由三部分組成:

  • 表現組件
  • 應用邏輯
  • 數據存取

表現組件負責與用戶交互,包括顯示數據和收集輸入。它多是一個帶有按鈕、列表、菜單等的現代GUI界面,也多是一個較舊的命令行風格的界面,用於提問和獲取答案。在這個概念層次上,細節並不重要。

應用程序邏輯負責解釋用戶的響應、應用業務規則、準備查詢和管理來自組件的響應。

數據存儲組件負責存儲和檢索數據。這一般會經過數據庫進行,但也不必定。

Gartner分類

基於這種應用程序的三重分解, Gartner考慮了組件在客戶端-服務器系統中的分佈方式, 他們提出了五種模型:

樣例:分佈式數據庫

Gartner 分類:1

現代手機就是一個很好的例子:因爲內存有限,它們可能在本地存儲數據庫的一小部分,這樣它們一般能夠快速響應。可是,若是須要的數據不是本地保存的數據,那麼可能會向遠程數據庫發出請求以獲取這些額外的數據。

谷歌地圖是另外一個很好的例子。全部地圖都位於Google的服務器上。當用戶請求時,「附近」的地圖也會被下載到瀏覽器中的一個小數據庫中。當用戶稍微移動地圖時,所需的額外數據已經在本地存儲中,能夠快速響應。

樣例:網絡文件服務

Gartner 分類:2容許遠程客戶端訪問共享文件系統

這種系統有不少例子:NFS,Microsoft共享,DCE等等。

樣例:網頁

Gartner 分類 3的一個例子是使用Java applet的網頁。這是一個分佈式超文本系統,具備許多其餘機制。

樣例:終端仿真

Gartner 分類 4的一個例子是終端模擬。它容許遠程系統充當本地系統上的普通終端。

Telnet是最多見的例子。

樣例:Expect

Expect是Gartner分類5的一個新穎示例。它就像一個經典系統(好比命令行界面)的包裝器。它圍繞此構建一個X Window接口,以便用戶與GUI交互,而後GUI又與命令行界面交互。

樣例:X窗口系統

X Window系統自己就是Gartner分類 5的一個例子。應用程序執行諸如DrawLine之類的GUI調用,但這些調用不是直接處理,而是傳遞給X Window服務器進行渲染。這解耦了窗口的應用程序視圖和窗口的顯示視圖。

三層模型

固然,若是有兩層,那麼能夠有三層、四層或更多層。圖中顯示了三層中的一些可能性:

現代Web就是其中最右邊的一個很好的例子。後端由數據庫組成,一般運行存儲過程來保存一些數據庫邏輯。中間層是一個HTTP服務器,例如Apache運行PHP腳本(或Ruby on Rails,或JSP頁面等)。這將管理一些邏輯,而且將數據,如HTML頁面存儲在本地。 前端是一個瀏覽器,在一些Javascript的控制下顯示頁面。在HTML 5中,前端也可能有一個本地數據庫。

重 V.S. 輕

組件的一個常見標籤就是「重」和」輕「。重型組件佔用大量內存並進行復雜處理。另外一方面,輕型組件對這兩種狀況都幾乎不起做用。彷佛沒有任何「正常」大小的成分,只有重和輕。

重和輕是一個相對的概念。瀏覽器一般被貼上「瘦」的標籤,由於「它們所作的只是顯示網頁」。我Linux上的Firefox佔用了將近1 / 2千兆字節的內存,我認爲這一點都不小!

中間件

中間件模型

中間件是鏈接分佈式系統組件的技術「粘合劑/膠水」。中間件模型是

中間件

中間件的組件包括:

  • 包括像TCP/IP這樣的網絡服務
  • The middleware layer is application-independent s/w using the network services.
  • 中間件的例子有:DCE、RPC、Corba
  • 中間件可能只執行一個功能(如RPC)或多個功能(如DCE)

中間件樣例

中間件的例子包括:

  • 終端模擬器,文件傳輸,電子郵件等基礎服務
  • RPC等基本服務
  • 綜合服務,如DCE,網絡O / S
  • 分佈式對象服務,如CORBA,OLE / ActiveX
  • 移動對象服務,如RMI、Jini
  • 萬維網

中間件功能

中間件的功能包括:

  • 在不一樣計算機上啓動/初始化進程
  • 會話管理
  • 容許客戶端定位服務器的目錄服務
  • 遠程數據訪問
  • 容許服務器處理多個客戶端的併發控制
  • 安全和完整性
  • 監控
  • 終止本地和遠程進程

持續處理過程

Gartner模型基於將應用程序分解爲表示組件、應用程序邏輯和數據處理組件。更細粒度的分解是:

故障點

分佈式應用程序運行在複雜的環境中。這使得它們比單個計算機上的獨立應用程序更容易出現故障。 失敗的緣由包括:

  • 應用程序的客戶端可能會崩潰
  • 客戶端系統可能存在硬件問題
  • 客戶端的網卡可能出現故障
  • 網絡爭用可能致使超時
  • 可能存在網絡地址衝突
  • 路由器等網絡元件可能會出現故障
  • 傳輸錯誤可能會丟失消息
  • 客戶端和服務器版本可能不兼容
  • 服務器的網卡可能會出現故障
  • 服務器系統可能有硬件故障
  • 服務器軟件可能會崩潰
  • 服務器的數據庫可能損壞

應用程序在設計時必須考慮到這些可能發生的故障。若是系統的其餘部分發生故障,一個組件執行的任何操做都必須是可恢復的。須要使用諸如事務和連續錯誤檢查等技術來避免錯誤。

驗收因素

  • 可靠性
  • 性能
  • 響應
  • 可伸縮性
  • 容量
  • 安全

透明性

分佈式系統的「聖盃」將提供如下內容:

  • 訪問透明
  • 位置透明
  • 遷移透明
  • 複製透明
  • 併發透明
  • 伸縮透明
  • 性能透明
  • 鼓掌透明

分佈式計算的八個謬論

SSun Microsystems是一家在分佈式系統中完成大部分早期工做的公司,甚至還有一句口號「網絡就是計算機」。 根據他們多年的經驗,Sun公司的一些科學家提出瞭如下常見的謬誤:

  • 網絡是可靠的
  • 延遲爲零
  • 帶寬是無限的
  • 網絡是安全的
  • 拓撲是不變的
  • 只有一個管理員
  • 傳輸成本爲零
  • 網絡是同質的(homogeneous)

其中許多直接影響到網絡編程。例如,大多數遠程過程調用系統的設計都基於這樣一個前提:網絡是可靠的,所以遠程過程調用的行爲將與本地調用相同。零延遲和無限帶寬的謬誤也致使RPC調用的持續時間與本地調用的持續時間相同的假設,而它們是數量級變慢的。

對這些謬誤的認識致使Java的RMI(遠程方法調用)模型要求每一個RPC調用均可能拋出RemoteException。這迫使程序員至少認識到網絡錯誤的可能性,並提醒他們不能期待與本地調用有相同的速度。

相關文章
相關標籤/搜索