Web 分散式系統的架構與其他分散式系統並無本質差異,但有趣的是觀察它從 1990 年代「支援分散式文件」的初衷一路演變至今:文件從純靜態、被動的內容,變成動態產生、包含各種主動元素;近年來許多組織更進一步轉向提供服務而非僅僅文件。以下討論這些轉變對架構的影響。
傳統 Web 系統#
許多 Web 系統至今仍是相對簡單的客戶端—伺服器架構:
- 一個網站的核心是一個能存取本地檔案系統(存放文件)的行程。
- 引用文件最簡單的方式是統一資源定位符(Uniform Resource Locator, URL):它指出文件的位置——通常內嵌所屬伺服器的 DNS 名稱與檔名,讓伺服器能在本地檔案系統中查找該文件——同時也指定跨網路傳輸文件所用的應用層協定。
- 客戶端透過**瀏覽器(browser)**與 Web 伺服器互動:瀏覽器負責正確顯示文件,並接受使用者輸入——多半是讓使用者點選另一份文件的連結,隨後抓取並顯示之。
- 瀏覽器與伺服器之間的通訊已標準化:雙方都遵循超文本傳輸協定(HyperText Transfer Protocol, HTTP)。

圖 12-1:傳統 Web 網站的整體組織
Web 文件#
Web 的根本在於幾乎所有資訊都以「文件」的形式呈現,而文件的概念要從最廣義理解:不只純文字,還可包含音訊、視訊、動畫等各種動態元素。許多情況下需要特殊的輔助應用程式(通常整合進瀏覽器)讓文件「活起來」。
多數文件可粗分為兩部分:主體部分至少充當模板,其餘則是共同構成顯示內容的各種零件。主體通常以標記語言(markup language)撰寫:
- HTML(HyperText Markup Language):Web 上最廣泛使用的標記語言,允許嵌入指向其他文件的連結;在瀏覽器中觸發連結時,被引用的文件會從其所屬伺服器抓取。
- XML(Extensible Markup Language):重要性日增的元標記語言(meta-markup language)——與 HTML 最大的差異在於 XML 本身包含「標記元素的定義」,不必受制於固定標記語言的單一模型,因此在指定文件外觀上彈性大得多。
HTML 與 XML 都能包含引用**內嵌文件(embedded documents)**的標籤,即為使文件完整而必須納入的檔案。可以說內嵌文件讓 Web 文件變得「主動」——尤其當內嵌文件是一支在顯示過程中即時執行的完整程式時。
內嵌文件五花八門,隨之而來的問題是:瀏覽器如何處理各種檔案格式?本質上只需要兩件事:指定內嵌文件型別的方法,以及讓瀏覽器處理特定型別資料的方法。
- 每份(內嵌)文件都有對應的 MIME 型別。MIME(Multipurpose Internet Mail Exchange)原本是為了描述電子郵件訊息主體的內容而發展,區分多種訊息內容型別,這些型別也沿用到 WWW;但新資料格式幾乎天天冒出,標準化並不容易。
- MIME 區分頂層型別(top-level type)與子型別(subtype):常見頂層型別包括 text、image、audio、video;特殊的 application 型別表示文件內容與特定應用程式相關,實務上只有該應用程式能把文件轉成人類可理解的東西;multipart 型別用於複合文件,每個部分再各自擁有頂層型別。
- 文件型別以「頂層型別/子型別」的組合表示,例如 application/PDF——表示需要另外的應用程式來處理這份 PDF 文件。許多子型別是實驗性的,需要自己專屬的應用程式;實務上由 Web 伺服器提供該程式,可能是瀏覽器旁執行的獨立程式,或是安裝為瀏覽器一部分的外掛(plug-in)。

圖 12-2:六種 MIME 頂層型別與一些常見子型別
文件型別不斷變動的多樣性,迫使瀏覽器必須可擴充。為此已有一定程度的標準化,讓遵循特定介面的外掛能輕易整合進瀏覽器;當某些型別夠流行時,往往就直接隨瀏覽器或其更新一起出貨。
多層式架構#
HTML(或 XML 等其他標記語言)加上腳本(scripting)是表達文件的強大手段,但文件究竟在哪裡處理、做了什麼處理?WWW 從簡單的兩層式客戶端—伺服器系統起步,如今已擴充了許多元件來支援進階的文件型態。
- **CGI(Common Gateway Interface)**是最早的擴充之一:它定義了一套標準方式,讓 Web 伺服器可以執行一支以使用者資料為輸入的程式。使用者資料通常來自 HTML 表單,表單指定要在伺服器端執行的程式與使用者填入的參數值;伺服器收到請求後啟動該程式並傳入參數,程式做完工作後通常以文件形式回傳結果給瀏覽器顯示。
- 有趣的觀察是:對伺服器而言,它就像在請 CGI 程式「抓一份文件」——伺服器只是把抓取文件的工作委派給外部程式,本身完全不知道文件是即時產生還是真的從本地檔案系統讀出。這是伺服器端軟體的兩層式組織。

圖 12-3:使用伺服器端 CGI 程式的原理
- 伺服器也能在把文件交給客戶端之前先處理它:文件可包含伺服器端腳本(server-side script),伺服器在本地取得文件後執行腳本,把執行結果連同文件其餘部分一起送給客戶端——腳本本身不會送出。換言之,伺服器端腳本等於「以執行結果取代腳本」來改寫文件。
- 隨著伺服器端處理需要更多彈性,許多網站現在採三層式架構:Web 伺服器、應用程式伺服器(application server)、資料庫。例如伺服器接受顧客查詢、搜尋資料庫中符合的商品、再組出可點選的商品列表頁面;許多情況下由伺服器執行稱為 servlet 的 Java 程式,維護購物車、推薦、喜好清單等。
三層式組織帶來一個問題:效能下降。架構上區分三層很合理,但實務顯示應用程式伺服器與資料庫是潛在瓶頸,尤其改善資料庫效能可能非常棘手。快取與複製作為效能解方,見本章「一致性與複製」一節。
Web 服務#
至今我們都隱含假設客戶端軟體就是「給使用者當介面的瀏覽器」,這個假設已不再普遍成立。有一群快速成長的 Web 系統,是在沒有終端使用者即時互動的情況下對遠端應用程式提供一般性服務——這就是 Web 服務(Web services) 的概念。
Web 服務基礎#
簡單說,Web 服務就是一個透過網際網路提供的傳統服務(命名服務、氣象服務、電子供應商等)。它的特殊之處在於遵循一組標準,使得同樣遵循標準的客戶端應用程式能在網際網路上發現並存取它——這些標準構成了 Web 服務架構的核心:
- UDDI(Universal Description, Discovery and Integration):目錄服務標準,規定存放服務描述的資料庫版面配置,讓 Web 服務客戶端能瀏覽尋找相關服務。
- WSDL(Web Services Definition Language):描述服務的正規語言,非常類似支援 RPC 通訊的介面定義語言。WSDL 描述包含服務介面的精確定義——程序規格、資料型別、服務的(邏輯)位置等。重要的是,WSDL 描述可自動轉譯成客戶端與伺服器端的 stub,與一般 RPC 系統產生 stub 的方式類似。
- SOAP(Simple Object Access Protocol):規定通訊如何進行的框架,讓兩個行程之間的大部分通訊得以標準化(詳見「通訊」一節——屆時也會發現稱它「簡單」名不符實)。

圖 12-4:Web 服務的原理
Web 服務的基本原理——標準化服務描述使其可被查找、確保呼叫遵循伺服器端訂的規則——與實現遠端程序呼叫(RPC)所需的東西並無不同。
Web 服務的組合與協調#
單一呼叫的模型在實務上不夠:一個服務往往需要多個步驟依特定順序完成才算結束。例如電子書店訂書需要選書、付款、確保送達——實際的服務應建模為由多個基本服務組成的交易。
更複雜的情況是組合不同供應商的 Web 服務。典型例子是 Web 商店:大致分成選貨、付款、出貨與追蹤三部分。供應商可能想用電子銀行服務處理付款、用專門的遞送服務處理出貨,自己專注於核心業務(賣貨)。此時顧客看到的必須是一個連貫的服務,但內部可能有三個組織需要協調行動。支援這種複合服務至少要解決兩類問題:不同組織的 Web 服務之間如何協調?服務如何容易地組合?
- 協調透過**協調協定(coordination protocols)**處理:協定規定複合服務成功所需的各個步驟,難處在於讓參與方在正確的時刻採取正確的步驟。最簡單的做法是由單一協調者控制參與方之間交換的訊息。
- 從 Web 服務的角度,重要的是把協調協定的共通處標準化:參與方要知道該與哪些行程通訊、要能識別協定的實例(一個行程可能同時參與多個協調協定)、也要知道自己扮演什麼角色。這些議題標準化為 Web Services Coordination:架構上它定義一個獨立的協調服務,行程可註冊為參與者,讓同伴知道彼此。
延伸案例:以協調服務實作 2PC
以第 8 章討論過的兩階段提交協定(two-phase commit, 2PC)的變體為例:協調服務要為各協定實例實作協調者。一種明顯的實作是由單一行程擔任多個協定實例的協調者;另一種是每個協調者由獨立的執行緒實作。
流程如下:某行程請求啟動特定協定,取得一個識別碼,把它傳給其他行程用來註冊為這個新建協定實例的參與者。所有參與行程都必須實作該協定的特定介面。全部註冊完成後,協調者就能在需要時對參與者送出 VOTE_REQUEST、COMMIT 等 2PC 協定訊息。
由於 2PC 這類協定的高度共通性,標準化介面與訊息會讓 Web 服務的組合與協調容易許多——實際要做的工作並不難,協調服務的附加價值完全在於標準化。
協調服務有一個潛在問題:服務如何組合是公開的,任何競爭者都能照樣搭出一模一樣的複合服務。因此需要建立私有協調者(private coordinators)的機制;這類組合技術仍在快速變動中,細節不涉及服務組合的原理,此處不深入。