分散式系統:程序間通訊

乌漆WhiteMoon發表於2024-03-13

目錄
  • 程序間通訊概述
  • 網際網路協議 API
    • 程序間通訊的特徵
    • 套接字
      • UDP 資料包通訊
      • TCP 流通訊
  • 外部資料表示和編碼
    • 外部資料表示
    • 常用的表示和編碼方法
    • 遠端物件引用
  • 組播通訊
  • 網路虛擬化和覆蓋網路
  • 參考資料

程序間通訊概述

程序間通訊(interprocess communication)主要討論了分散式系統程序之間的通訊協議的特徵,資料包和流通訊機制為通訊協議提供了可互換的構造成分。UDP 的應用程式介面提供了訊息傳遞(message passing)抽象,使得一個傳送程序能夠給一個接收程序傳遞一個訊息。UDP 實現的是程序間通訊的最簡單形式,包含這些訊息的獨立的資料包稱為資料包(datagram)。TCP 的應用程式介面提供了程序對之間的雙向流(two-way stream)抽象,相互通訊的資訊由沒有訊息邊界的一連串資料項組成。這些用於程序間通訊的服務支援點對點通訊,而且也能實現組播通訊,也就是從一個傳送者傳送一個訊息給一組接收者。訊息傳遞介面(Message Passing Interface, MPI)是一個標準,為一組具有同步和非同步支援的訊息傳遞操作提供 API。

網際網路協議 API

程序間通訊的特徵

一對程序間進行的訊息傳遞由 send 和 receive 這兩個訊息通訊操作來支援,它們均用目的地和訊息定義。程序通訊時由一個程序傳送一個訊息(位元組序列)到目的地,在目的地的另一個程序接收訊息。每個訊息目的地與一個佇列相關,傳送程序將訊息新增到遠端佇列中,接收程序從本地佇列中移除訊息。
程序之間的通訊可以是同步的也可以是非同步的,在同步(synchronous)形式的通訊中,傳送程序和接收程序在每個訊息上同步。此時 send 和 receive 都是阻塞操作,傳送程序發出一個 send 操作後將一直阻塞,直到傳送了相應的 receive 操作為止。每次傳送一個 receive 後,程序將一直阻塞,直到訊息到達為止。

非同步(asynchronous)形式的通訊中,send 操作是非阻塞的,只要訊息被複制到本地緩衝區,傳送程序就可以繼續進行其他處理。receive操作有阻塞型和非阻塞型兩種形式:在不阻塞的 receive 操作中,接收程序在發出 receive 操作後可繼續執行它的程式;在支援多執行緒的系統環境中,在一個執行緒發出阻塞型 receive 操作時,該程序中的其他執行緒仍然是活動的。非阻塞型的通訊看上去更有效,但接收程序需要從它的控制流之外獲取到達的訊息,這涉及額外的複雜工作。

本地埠是計算機內部的訊息目的地,用一個整數指定,一個埠只能有一個接收者但可以有多個傳送者。程序可以使用多個埠接收訊息,任何知道埠號的程序都能向埠傳送訊息。可靠通訊需要滿足有效性和完整性,有效性指的是如果一個點對點訊息服務在丟失了“合理”數量的資料包後,仍能保證傳送訊息,那麼該服務就被稱為可靠的。相反只丟失一個資料包,訊息就不能保證傳送,那麼這個點對點訊息服務仍是不可靠的。完整性指的是到達的訊息必須沒有損壞,且沒有重複。有些應用要求訊息要按傳送方的順序傳送,與傳送方順序不一致的訊息傳送會被這樣的應用認為是失敗的傳送。

套接字

UDP 和 TCP 都使用套接字(socket)抽象,它提供程序間通訊的一個端點,程序間通訊是在兩個程序各自的一個套接字之間傳送一個訊息。對接收訊息的程序,它的套接字必須繫結到計算機的一個網際網路地址和一個本地埠,傳送到特定網際網路地址和埠號的訊息只能被一個對應的套接字相關的程序接收。程序可以使用同一套接字傳送和接收訊息,任意一個程序可利用多個埠來接收訊息,但一個程序不能與同一臺計算機上的其他程序共享埠。

UDP 資料包通訊

由 UDP 傳送的資料包從傳送程序傳輸到接收程序,不需要確認或重發,如果發生故障則訊息可能無法到達目的地。要傳送或接收訊息,程序必須建立與一個本地主機的網際網路地址和本地埠繫結的套接字,伺服器將把套接字繫結到一個伺服器埠(server port)。客戶客戶將它的套接字繫結到任何一個空閒的本地埠,給該埠傳送訊息。Receive 方法除了獲得訊息外,還獲得傳送方的網際網路地址和埠,用於允許接收方傳送應答。

以下是一些資料包通訊的機制設定:

資料包通訊機制 說明
訊息大小 接收程序要指定固定大小的用於接收訊息的位元組陣列,如果訊息大於陣列大小,則訊息在到達時會被截斷
阻塞 send 操作將訊息傳遞給 UDP 和 IP 協議後就返回,除非設定了超時,否則 receive 方法將一直阻塞直到接收到一個資料包為止
超時 傳送程序可能崩潰或期待的訊息已經丟失,阻塞的 receive 操作不適合無限制地等待下去,此時要在套接字上設定超時
任意接收 呼叫 receive 可以獲得從任何來源發到它的套接字上的訊息,並返回傳送方的網際網路地址和本地埠,允許接收方檢查訊息的來源

UDP 資料包存在下列故障,如果想獲得所要求的可靠通訊的質量,應用要自己提供檢查手段,可以利用確認機制將一個有遺漏故障的服務構造為可靠傳送服務。

UDP 資料包故障 說明
遺漏故障 可能是因為校驗和錯誤或者在傳送端或目的端沒有可用的緩衝區空間,訊息偶爾會丟失
排序 訊息有時沒有按傳送方順序傳送

對某些應用而言,使用偶爾有遺漏故障的服務是可接受的,例如 DNS、VOIP 等。UDP 資料包沒有與保證訊息傳遞相關的開銷,因此有時是一個很有吸引力的選擇,它開銷主要源自三個方面:在源和目的地儲存狀態資訊、傳輸額外的訊息、傳送方的延遲。

TCP 流通訊

TCP 流通訊的 API 假設,建立連線時由客戶程序向伺服器程序發起請求,建立連線後兩個程序是平等的。客戶角色需要建立繫結到埠的流套接字,然後發出 connect 請求,在伺服器的埠上請求與伺服器連線。伺服器角色需要建立繫結到伺服器埠的監聽套接字,然後等待客戶請求連線。監聽套接字維護到達的連線請求佇列,當伺服器 accept 一個連線,就建立一個新的流套接字用於與客戶的通訊,同時保持在伺服器埠上的套接字用於監聽其他客戶的comnect 請求。客戶和伺服器的套接字對由一對流相連線,程序對中的任何一個程序都可以透過將資訊寫入它的輸出流來傳送資訊給另一個程序,而另一個程序透過讀取它的輸入流來獲得資訊。當一個應用 close 一個套接字時,表示它不再寫任何資料到它的輸出流,輸出緩衝區中的任何資料被送到流的另一端,並指明流已斷開了。當程序退出或失敗時,它的所有套接字最終被關閉,任何試圖與它通訊的程序將發現連線已中斷。

以下是一些流通訊的機制設定:

流通訊機制 說明
訊息大小 應用能選擇它寫到流中和從流中讀取的資料量,如果有必要應用可以強制資料馬上傳送
丟失的訊息 如果在一個超時時間段內,傳送方沒有接收到確認資訊,則傳送方重傳該訊息
流控制 如果對讀取流的程序來說寫人流的程序太快,那麼它會被阻塞直到讀取流的程序消化掉足夠的資料為止
訊息重複和排序 每個 IP 資料包與訊息識別符號相關聯,接收方能檢測和丟棄重複的訊息,或重排沒有按序到達的訊息
訊息目的地 建立連線後,程序不需要使用網際網路地址和埠即可讀、寫流

以下是一些與流通訊相關的問題:

流通訊的重要問題 說明
資料項的匹配 兩個通訊程序需要對在流上傳送的資料的內容達成一致
阻塞 如果在另一端的套接字佇列中的資料與協議允許的資料一樣多,則將資料寫入流的程序可能被 TCP 流控制機制阻塞
執行緒 接受連線時通常是建立一個新執行緒進行通訊,此時伺服器在等待輸入時能阻塞而不會延誤其他客戶

為保證完整性,TCP 流使用校驗和檢查並丟棄損壞的資料包,使用序列號檢測和丟棄重複的資料包。為保證有效性,TCP 流使用超時和重傳來處理丟失的資料包。因此即使底層有些資料包丟失,還是可以保證訊息的傳輸。但是如果連線上的資料包丟失超過了限制,以及連線一對通訊程序的網路不穩定或嚴重擁塞,則負責傳送訊息的 TCP 軟體將收不到確認。這種情況持續一段時間之後,TCP 就會宣告該連線已中斷,此時就不能提供可靠通訊了。這會造成下列後果:

  1. 使用連線的程序不能區分是網路故障還是連線另一端的程序故障;
  2. 通訊程序不能區分最近它們傳送的訊息是否已被接收。

許多經常使用的服務都是使用保留的埠號,在 TCP 連線上執行的,例如:

基於 TCP 的服務 協議名稱 說明
HTTP 超文字傳送協議 用於Web瀏覽器和 Web 伺服器之間的通訊
FTP 檔案傳輸協議 允許瀏覽遠端計算機上的目錄,以及透過連線將檔案從一臺計算機傳輸到另一臺計算機
telnet telnet 利用終端會話訪問遠端計算機
SMTP 簡單郵件傳輸協議 用於在計算機之間傳送郵件

外部資料表示和編碼

外部資料表示

訊息中的資訊由位元組序列組成,因此不論使用何種通訊形式,記憶體中的資料結構在傳輸前必須轉換成位元組序列,到達目的地後重構。在訊息中傳送的單個簡單資料項可以是不同型別的資料值,不是所有的計算機都以同樣的順序儲存整數這樣的簡單值,用於表示字元的程式碼集也可能不同。下列方法可用於使兩臺計算機交換資料值:

  1. 值在傳送前先轉換成一致的外部格式,然後在接收端轉換成本地格式。如果兩臺計算機是同一型別,可以不必轉換成外部格式。
  2. 值按照傳送端的格式傳送,同時傳送所使用格式的標誌,接收方會根據需要轉換該值。

為了支援 RMI 或 RPC,任何能作為引數傳遞或作為結果返回的資料型別必須被序列化,令資料值以一致的格式表示。表示資料結構和簡單值的一致的標準稱為外部資料表示,透過編碼和解碼兩個步驟完成。編碼是將多個資料項組裝成適合訊息傳送的格式的過程,將結構化資料項和簡單值翻譯成外部資料表示。解碼是在訊息到達後分解訊息,在目的地生成相等的資料項的過程,也就是從外部資料表示生成簡單值並重建資料結構。

常用的表示和編碼方法

以下是三種常用的外部資料表示和編碼的方法,在前兩種情況下,編碼和解碼活動均由中介軟體層完成,XML 的編碼和解碼軟體也對所有平臺和程式設計環境可用。編碼要求考慮組成組合物件的簡單元件的表示細節,所以如果手工完成該過程,那麼整個過程很容易出錯。在前兩個方法中,簡單資料型別被編碼成二進位制形式,在 XML 中簡單資料型別表示成文字,通常資料值的文字表示將比等價的二進位制表示更長。另一個問題是被編碼資料是否應該包括與其內容的型別有關的資訊,CORBA 的表示只包括所傳送的物件的值不包含它們的型別。序列化和 XML 都包括了型別資訊,序列化把所有需要的型別資訊放到格式中,XML 文件可以指向型別的外部定義集合,即名字空間(namespace)。

流通訊的重要問題 說明
CORBA 在 CORBA 的遠端方法呼叫中能作為引數和結果傳送的結構化型別和簡單型別的外部表示
物件序列化 涉及需要在訊息中傳送或儲存到磁碟上的單個物件或物件樹的序列化和外部資料表示
XML 定義了表示結構化資料的文字格式,用於在 Web 服務中被客戶和伺服器交換的訊息中的資料

遠端物件引用

遠端物件引用僅適用於諸如 Java 和 CORBA 這樣的支援分佈物件模型的語言,與 XML 無關。客戶呼叫遠端物件中的一個方法時,就會向存放遠端物件的伺服器程序傳送一個呼叫訊息,這個訊息指定哪一個物件具有要呼叫的方法。遠端物件引用(remote object reference)是遠端物件的識別符號,用於指定呼叫哪一個物件,在整個分散式系統中有效。
通常在遠端物件上有許多程序,因此遠端物件引用必須以確保空間和時間唯一性的方法生成。即使在刪除與給定遠端物件引用相關的遠端物件後,該遠端物件引用也不能被重用。一種方法是透過拼接計算機的網際網路地址、建立遠端物件引用的程序的埠號、建立時間和本地物件編號來構造遠端物件引用。在 RMI 的最簡單實現中,遠端物件僅在建立它們的程序中存在,並只在該程序執行時存活,此時遠端物件引用可以作為遠端物件的地址。

組播通訊

有時候一個程序與一組程序通訊可能是必要的,例如為了提供容錯能力或為了提高可用性,將一個服務實現為多個不同計算機上的多個不同的程序。組播操作(multicast operation)是更合適的方式,這是一個將單個訊息從一個程序傳送到一組程序的每個成員的操作,組的成員對傳送方通常是透明的。組播訊息為構造具有下列特徵的分散式系統提供了基礎設施:

基於組播的分散式系統設施 說明
基於複製服務的容錯 客戶請求被組播到組的所有成員執行相同的操作,即使一些成員出現故障,仍能為客戶提供服務
在自發網路中發現服務 使用組播訊息找到可用的發現服務,以便在分散式系統中註冊服務介面或查詢其他服務的介面
透過複製的資料獲得更好的效能 資料的副本有時可以放在使用者的計算機上,每次資料改變,新的值便被組播到管理副本資料的各個程序
事件通知的傳播 在發生某些事情時導致狀態改變時,通知有關程序

IP 組播(IP multicast)在網際協議 IP 的上層實現,使傳送方能夠將單個 IP 資料包傳送給組成組播組的一組計算機。組播組(multicast group)由 D 類網際網路地址指定,組播組的成員允許計算機接收傳送給組的 IP 資料包。組播組的成員是動態的,計算機可以在任何時間加入或離開,計算機也可以加入任意數量的組。IP 組播只能透過 UDP 可用,應用程式透過傳送具有組播地址和普通的埠號的 UDP 資料包完成組播。在 IP 層當一個或多個程序具有屬於一個組播組的套接字時,該計算機屬於這個組播組。當一個組播訊息到達計算機時,訊息副本被轉發到所有已經加人到指定組播地址和指定埠號的本地套接字上。

IPv4 組播有一些特有的機制,IP 資料包可以再區域網或網際網路上組播,其中網際網路上的組播利用了組播路由器,由它將單個資料包轉發到其他成員所在網路的路由器上,再透過路由器組播到本地成員。在組播地址分配方面,D 類地址(224.0.0.0~239.255.255.255)作為組播通訊的保留地址,組播地址可以是永久的,也可以是暫時的。剩下的組播地址可用於臨時組,這些組必須在使用前建立,在所有成員離開的時候消失。

IP 組播上的資料包組播與 UDP 資料包有相同的故障特徵,也就是說 IP 組播也會存在遺漏故障。從一個組播路由器傳送到另一個路由器的資料包也可能丟失,這妨礙了另一端路由器的接收者接收訊息。對區域網的組播而言,任何一個接收者都可能因為它的緩衝區已滿而丟棄訊息。還有一個問題是排序,在網路上傳送的 IP 資料包不一定按序到達,此時組中的一些成員從同一個傳送者處接收的資料包的順序可能與其他組成員接收的順序不一樣。

網路虛擬化和覆蓋網路

不斷增加的大量不同型別的應用在網際網路上並存,試圖更改網際網路協議來適應執行在其上的每一個應用是不實際的,而且大量持續增多的網路技術都是使用 IP 服務實現的。這兩個因素促使了網路虛擬化,這個概念涉及在一個已有的網路之上構造多個不同的虛擬網路,每個虛擬網路被設計成支援一個特定的分散式應用。一種解決方案是,一個面向特定應用的虛擬網路能建在一個已有的網路上並進行針對性的最佳化,而不改變底層網路的特徵。
覆蓋網路(overlay network)是一個結點和虛擬連結組成的虛擬網路,位於一個底層網路(如 IP 網路)之上,能提供如下所示的一些獨有的功能。覆蓋網路使得不改變底層網路就能定義新的網路服務,同時鼓勵了對網路服務進行實驗和對服務進行面向特定應用的定製。覆蓋網開發者能自由地重定義網路的核心元素,包括定址的模式、所採用的協議和路由的方法,能針對操作環境的特定應用進行裁剪。實踐上能定義多個同時存在的覆蓋網(overlay),從而形成更開放和可擴充套件的網路體系結構。覆蓋網的不足是引入了額外的間接層,增加了網路服務的複雜性。

  1. 滿足一類應用需求的服務或一個特別高層的服務,例如多媒體內容的分發;
  2. 在一個給定的聯網環境中的更有效的操作,例如在一個自組織網路中的路由;
  3. 提供一些額外的功能,例如組播或安全通訊。

Skype 是一個在 IP 上提供語音電話服務(Voice over IP,VoIP)的對等應用,它在不修改網際網路核心體系結構的前提下以應用特定的方式提供高階功能。Skype 基於對等基礎設施,由普通使用者的機器(稱為宿主機)和超級結點組成,超級結點是有足夠的能力完成其增強角色的普通 Skype 宿主機。超級結點基於一系列標準按需選擇出來的,包括可用的頻寬、可達性和可用性。Skype 使用者透過一個眾所周知的登入伺服器進行認證,接著他們可以與一個選中的超級結點連線。超級結點的主要目的是完成對使用者全域性索引的搜尋,整個搜尋由客戶所選中的超級結點進行協調,會涉及擴充套件到其他超級結點的搜尋,直到找到所指定的使用者。一旦發現了所請求的使用者,Skype 就在雙方之間建立一個聲音連線,用 TCP 觸發呼叫請求和呼叫終止,用 UDP 或 TCP 傳輸流或音訊。

參考資料

《分散式系統概念與設計》[英]George Coulouris, Jean Dollimore, Tim Kindberg,Gordon Blair,金蓓弘,馬應龍 譯,機械工業出版社

相關文章