01

認識 Web 服務

Web 服務的定義、與 web server 的差別,以及它在分散式系統中的整體架構圖。

先讀原文開場,旁邊就是白話

這是一本英文書。左邊放原文、右邊放白話導讀——你既讀得懂,也順手碰了原文。

原文 · Web 服務 3 Service descriptions and IDL for web services 9. 4 A directory service for use with web services 9. 6 Coordination of web services 9. 7 Applications of web services 9.
白話導讀

Web 服務的定義、與 web server 的差別,以及它在分散式系統中的整體架構圖。

什麼是 Web 服務

Web 服務的定義、與 web server 的差別,以及它在分散式系統中的整體架構圖。

STEP 1

深度探秘

讓程式而不是人去用網路服務

Web 服務到底是什麼

你用瀏覽器看網頁時,是在點選、閱讀。但很多時候,我們希望是程式直接去跟遠端伺服器要資料、下訂單,完全不需要人盯著螢幕。這正是 Web 服務 (web service) 的舞台。

Web 服務提供一個服務介面 (service interface),讓客戶端程式能用比瀏覽器更一般化的方式跟伺服器互動。

關鍵字拆解:

  • 服務介面:一組可以被呼叫的操作(operation),例如「查商品資訊」「加入購物車」。
  • URI:每個 Web 服務都用一個 URI 來識別,最常見的形式就是 URL。
  • XML 訊息:客戶端與服務之間的請求和回覆,都用 XML 這種文字格式包裝,通常透過 HTTP 傳輸。

特別要分清楚兩個長得很像的詞:

名詞 提供什麼
web server(網頁伺服器) 基本的 HTTP 服務,把網頁丟給瀏覽器
web service(Web 服務) 以介面中定義的「操作」為基礎的服務

Web 服務可以由 web server 順便提供,也可以是完全獨立的服務。

💡
關鍵

Web 服務是給程式用的服務介面,用 URI 識別、用 XML 訊息溝通、常走 HTTP。

STEP 2

生活妙喻

餐廳的「外送 API 窗口」

把 Web 服務想成餐廳的外送窗口

想像一家餐廳:

  • 瀏覽器看網頁就像客人走進店裡,看菜單、點餐、和服務生聊天——很彈性,但一切都要親自來。
  • Web 服務則像餐廳開了一個專門給外送平台用的接單窗口。外送平台的系統(程式)直接送進一張結構化的訂單:「品項 A 兩份、地址在這」,餐廳系統就自動回一張「已接單、預計 20 分鐘」。

這個窗口的特性正好對應 Web 服務:

  • 固定的操作清單=介面(接單、查狀態、取消)。
  • 窗口的地址=URI/URL。
  • 訂單表格的格式=XML 訊息。
  • 送單的管道=HTTP。

重點是:這個窗口讓一家公司的系統可以跟另一家公司的系統自動對話,中間不需要有人手動操作。

💡
關鍵

瀏覽器看網頁像客人進店靠人;Web 服務像專給其他系統用的自動接單窗口。

STEP 3

實用超能力

看懂整體架構,把服務疊在服務上

Web 服務的整體架構

課本的 Figure 9.1 把整套基礎設施疊成一張圖。由下往上:

flowchart TD
  A[URIs 與 HTTP SMTP 等傳輸] --> B[XML]
  B --> C[SOAP 包裝訊息]
  C --> D[服務描述 WSDL]
  D --> E[應用程式與更高層服務]
  E --> F[目錄服務 安全 編排]
  • 最底層是 URI傳輸協定(HTTP、SMTP 等)。
  • 往上是 XMLSOAP,負責把訊息打包。
  • 再上面是服務描述(用 WSDL 寫),讓客戶端知道怎麼用這個服務。
  • 最上層是應用程式,而且一個 Web 服務可以建立在其他 Web 服務之上

真實例子:Amazon、Google、eBay 都開放 Web 服務介面。一個第三方的「採購應用程式」就能自動向 Amazon 下單補貨、追蹤訂單狀態,完全不用人去點網頁。這就是 Web 服務的超能力——讓服務像積木一樣互相堆疊組合。

💡
關鍵

Web 服務是一層層疊起來的基礎設施,且服務能堆在服務之上,組成更強大的應用。

🔆
生活妙喻:web server 與 web service 的差別 ≈ 大樓的「大廳接待」與「專業櫃台」

web server 像大廳接待,誰來都先給張通用的網頁;web service 像專業櫃台,只回應它介面上定義好的特定業務操作。

🔆
生活妙喻:用 URI 識別服務 ≈ 店家的門牌地址

就像你靠門牌找到一家店,客戶端靠 URI 找到並呼叫某個特定的 Web 服務。

本節字彙

service interface(服務介面)
一組可被客戶端呼叫的操作集合,定義了這個服務「能做什麼」。
🧠 interface=對外的『介面窗口』,列出可用的操作。
URI
識別資源的字串,Web 服務用它來被指認與呼叫,最常見形式是 URL。
🧠 URI=資源的『身分證字號』。
XML
一種自我描述的文字資料格式,雖然比較肥大,但人讀得懂、好除錯,被選為 Web 服務的訊息格式。
🧠 XML=用標籤把資料『包』起來的文字格式。
一家旅遊公司希望「自己的訂房系統」能自動向多家航空公司的系統查詢並訂位,全程不需要員工手動操作網頁。為什麼 Web 服務比讓員工用瀏覽器更適合?
同事說:「我們公司有跑 Apache web server,所以就等於有了 web service。」這句話哪裡有問題?
在 Web 服務的整體架構(Figure 9.1)中,SOAP 主要扮演什麼角色?

通訊模式與鬆耦合

同步請求-回覆、非同步訊息、事件三種溝通方式,以及 REST 風格與鬆耦合的多個面向。

STEP 1

深度探秘

三種對話方式與 REST 風格

Web 服務怎麼跟客戶端對話

Web 服務和客戶端之間,有幾種溝通模式:

  • 同步請求-回覆 (synchronous request-reply):送出請求,原地等著回覆。像打電話問問題,講完馬上聽答案。適合需要即時結果的情境,例如檢查信用卡。
  • 非同步訊息 (asynchronous messaging):送出請求後不傻等,回覆稍後才到。即使需要回覆也可以這樣,例如冗長的訂位流程。
  • 事件 (event) 風格:客戶端先「訂閱」感興趣的事件,之後服務有變化(如某服務上線/下線)就通知它。

為了支援這些模式,SOAP 以「單向訊息」為基礎:請求-回覆其實就是用一對單向訊息湊出來的。

REST 風格

除了 SOAP,還有一條路叫 REST (Representational State Transfer)

客戶端用 URL 加上 HTTP 的 GET、PUT、POST、DELETE 操作來操弄資源,資源用 XML 表示。

REST 強調操弄資料資源,而不是強調介面。有趣的是,Amazon 的 Web 服務請求中,約 80% 走 REST、20% 走 SOAP。

💡
關鍵

Web 服務可同步請求-回覆、非同步訊息或事件溝通;REST 則用 URL 加少數 HTTP 動詞操作資源。

STEP 2

生活妙喻

電話、留言條、與訂閱電子報

三種溝通像三種聯絡方式

  • 同步請求-回覆打電話:你問一句,對方馬上答,你一直握著話筒等。快,但雙方此刻是綁在一起的。
  • 非同步訊息留言條/email:你留個訊息走人,對方有空再回。你不用乾等,雙方時間鬆綁。
  • 事件風格訂閱電子報:你登記了 email,之後一有新消息系統就自動寄給你,你不用一直去問「有更新了嗎」。

鬆耦合就像「不黏太緊的合作關係」

鬆耦合 (loose coupling) 指的是:盡量減少服務之間的依賴,這樣改動一個服務比較不會像骨牌一樣牽連其他服務

達成鬆耦合的幾個手段:

  • 以介面寫程式:把『介面』和『實作』分開,換掉內部實作不影響呼叫方。
  • REST 的通用介面:少數固定動詞,降低對特定操作名稱的依賴,資料變得比操作更重要
  • 選擇通訊方式:請求-回覆兩方綁很緊;非同步訊息鬆一點;間接通訊則連時間和空間都能鬆綁。
💡
關鍵

同步像打電話、非同步像留言、事件像訂閱;鬆耦合就是讓服務間不要黏太緊。

STEP 3

實用超能力

為一個任務挑對的溝通模式

旅遊代理服務怎麼選模式

課本用『旅遊代理服務』示範如何混搭兩種模式:

子任務 適合的模式 為什麼
處理一筆訂位 非同步文件交換 流程很長:先送日期目的地,狀態陸續回報,最後才完成;速度不是重點
檢查信用卡、與客戶互動 請求-回覆 需要即時得到結果
flowchart TD
  A[客戶端送出訂位需求] --> B[非同步收集機票旅館租車資訊]
  B --> C[陸續回報狀態]
  C --> D[同步檢查信用卡]
  D --> E[完成訂位]

實務心法

  • 即時答案(如刷卡驗證)→ 用同步請求-回覆。
  • 流程冗長、可慢慢來(如整套訂位)→ 用非同步訊息,別讓客戶端乾等。
  • 想要鬆耦合、降低未來改動風險 → 考慮 REST 與間接通訊。

記住結論:鬆耦合有很多面向,用這個詞時要想清楚你指的是哪一種鬆綁。

💡
關鍵

依任務性質挑模式:要即時用同步、流程長用非同步、想鬆綁就用 REST 與間接通訊。

🔆
生活妙喻:同步 vs 非同步通訊 ≈ 打電話 vs 留言條

同步像打電話要握著話筒等答案,雙方此刻綁在一起;非同步像留張字條走人,對方有空再回,時間上鬆綁。

🔆
生活妙喻:鬆耦合 ≈ 用魔鬼氈而非強力膠黏東西

鬆耦合讓服務像魔鬼氈一樣易拆易換,改一邊不會把另一邊一起扯壞;緊耦合則像強力膠,動一處全都受影響。

🔆
生活妙喻:事件風格通訊 ≈ 訂閱電子報

客戶端先登記感興趣的事件,之後有變化系統自動通知,不必一直主動去問。

本節字彙

loose coupling(鬆耦合)
盡量減少服務之間的依賴,讓改一個服務時不易連帶影響其他服務。
🧠 loose=『鬆』,黏得越鬆,牽連越少。
REST
一種受限的風格,客戶端用 URL 與 GET PUT POST DELETE 操作以 XML 表示的資源,重資料而非介面。
🧠 REST=用『網址+四個動詞』搞定一切。
asynchronous messaging(非同步訊息)
送出訊息後不原地等待回覆,回覆稍後才非同步送達的溝通方式。
🧠 a-(非)+synchronous(同步)=不同步乾等。
旅遊代理服務在『處理一整筆冗長的訂位流程』時,最適合用哪種通訊模式?為什麼?
同一個旅遊代理服務在『檢查客戶信用卡』時,為何反而適合用同步請求-回覆?
REST 風格與傳統強調介面操作的方式相比,有什麼特色?
02

SOAP:Web 服務的共同語言

SOAP 如何用 XML 包裝請求與回覆,信封、標頭、本體的角色,以及 fault 錯誤回報。

SOAP 訊息與信封

SOAP 如何用 XML 包裝請求與回覆,信封、標頭、本體的角色,以及 fault 錯誤回報。

STEP 1

深度探秘

信封、標頭、本體與錯誤回報

SOAP 是什麼

SOAP 是 Web 服務最常用的通訊協定。它做的事就是:規範怎麼用 XML 來表示請求與回覆訊息,以及怎麼把它們傳出去。SOAP 原本只搭 HTTP,現在也能用 SMTP、TCP、UDP 等多種傳輸協定。

訊息的結構:信封

一則 SOAP 訊息裝在一個 envelope(信封) 裡,信封內含:

  • header(標頭,選用):給沿途的中介者 (intermediary) 用的。可放交易識別碼、訊息識別碼、使用者名稱、數位簽章或公鑰等。
  • body(本體,必備):裝給特定 Web 服務的 XML 內容——也就是實際的請求回覆
flowchart TD
  A[envelope 信封] --> B[header 標頭 選用]
  A --> C[body 本體 必備]
  B --> D[header element 如交易識別碼]
  C --> E[body element 如請求或回覆內容]

兩種用法與 fault

SOAP 訊息可以傳一份文件,也可以支援請求-回覆(body 裝 Request 或 Reply)。如果請求失敗,回覆訊息的 body 會放一個 fault 元素,裡面有錯誤碼、錯誤字串與應用特定細節。

💡
關鍵

SOAP 訊息裝在 envelope 裡:選用的 header 給中介者,必備的 body 裝請求/回覆,失敗時用 fault 回報。

STEP 2

生活妙喻

一封掛號信

SOAP 訊息就像一封掛號信

把 SOAP 訊息想成一封要寄出的掛號信

  • envelope(信封):整封信的外殼,把所有東西包在一起。
  • header(信封上的便利貼/批註):貼在信封上、給沿途郵差或經手人看的備註,例如「請掛號簽收」「轉交三樓會計」。SOAP 的 header 同樣是給中介者看的,他們可以讀取、增加、修改或移除這些資訊。
  • body(信紙本身):真正要給收件人讀的內容,也就是實際的請求或回覆。

fault 就像郵局退回信件時夾的那張**「無法投遞,原因如下」通知單**:上面有原因代碼、文字說明,告訴你哪裡出了問題。

關鍵體會:header 是過程中的人在乎的事(路由、記錄、安全),body 才是最終收件人真正關心的內容。

💡
關鍵

信封是外殼、header 是給沿途經手人的批註、body 是給收件人的信紙、fault 是退件通知單。

STEP 3

實用超能力

讀懂一則 SOAP 請求與回覆

看一個具體的請求/回覆

課本 Figure 9.4/9.5 示範一個 exchange 操作:傳兩個字串進去,服務把它們順序對調回傳。

請求(簡化):

<env:Envelope xmlns:env="...SOAP 信封命名空間...">
  <env:Body>
    <m:exchange xmlns:m="...服務描述命名空間...">
      <m:arg1>Hello</m:arg1>
      <m:arg2>World</m:arg2>
    </m:exchange>
  </env:Body>
</env:Envelope>

回覆(簡化):

<env:Envelope xmlns:env="...SOAP 信封命名空間...">
  <env:Body>
    <m:exchangeResponse xmlns:m="...服務描述命名空間...">
      <m:res1>World</m:res1>
      <m:res2>Hello</m:res2>
    </m:exchangeResponse>
  </env:Body>
</env:Envelope>

觀察重點:

  • body 內第一個元素的名字=要呼叫的程序名(exchange),其內層元素是引數。
  • 回覆的程序名會加上 Response(exchangeResponse)。
  • 兩個命名空間:env 定義 SOAP 信封,m 定義應用特定的程序與引數名稱。

好消息:實務上程式設計師通常不必手寫這些 XML——Java、Python、C# 等語言都有 SOAP API 幫你產生與解析。

💡
關鍵

請求 body 的第一個元素就是程序名,回覆名加上 Response;命名空間分別界定 SOAP 信封與應用內容。

🔆
生活妙喻:SOAP envelope/header/body ≈ 一封掛號信

信封是外殼,信封上的批註(header)給沿途郵差看,信紙(body)才是給收件人的真正內容。

🔆
生活妙喻:SOAP fault ≈ 郵局的退件通知單

請求失敗時,fault 像退回信件附的『無法投遞、原因如下』通知,含錯誤碼與說明。

🔆
生活妙喻:header 給中介者用 ≈ 包裹上的轉運貼紙

header 像包裹上一張張轉運與處理貼紙,中途的轉運站可讀取、加上或撕掉,最終收件人不一定在乎。

本節字彙

SOAP
Web 服務常用的通訊協定,規範如何用 XML 表示請求與回覆訊息並加以傳送。
🧠 把訊息『泡』進 XML 信封裡寄出。
envelope(信封)
包住整則 SOAP 訊息的最外層元素,內含選用的 header 與必備的 body。
🧠 envelope=信封,把整封訊息包起來。
fault(錯誤元素)
請求失敗時放在回覆本體中的元素,含錯誤碼、錯誤字串與應用特定細節。
🧠 fault=『故障』回報單。
你想在 SOAP 訊息裡放一個『交易識別碼』,讓沿途的交易中介服務能據此處理,但最終服務的核心邏輯不需要它。這個資訊最適合放在哪裡?
一個 SOAP 請求呼叫了名為 reserve 的操作。依 SOAP 慣例,對應的成功回覆裡的元素名稱最可能是什麼?
SOAP 訊息中為何要用到兩個不同的 XML 命名空間(例如 env 與 m)?

傳輸、定址與可靠傳遞

SOAP 與傳輸協定的分離、用 HTTP POST 傳送、穿越防火牆,以及 WS-Addressing 與 WS-ReliableMessaging。

STEP 1

深度探秘

把信封跟『怎麼寄』分開

SOAP 與傳輸協定刻意分離

SOAP 設計上有個重要決定:SOAP 訊息與傳輸協定無關。信封裡不含目的地位址,要送去哪,交給底下的傳輸協定(如 HTTP)去決定。

以 HTTP 為例(Figure 9.6),用 HTTP POST 傳送 SOAP 訊息:

  • HTTP 標頭指定端點位址 (endpoint address)(最終收件者的 URI)與要執行的 Action。Action 標頭讓伺服器不必拆開 SOAP 內容就知道要呼叫哪個操作,加速分派。
  • HTTP 本體承載 SOAP 訊息。

因為 HTTP 是同步協定,它順便把 SOAP 回覆帶回來。若只是查資料、沒引數又不改伺服器資料,也可用 HTTP GET

這種分離是強項也是弱點:強在能換用不同底層協定(甚至 SMTP);弱在開發者必須涉入所選協定的細節,也難在同一條路徑的不同段用不同協定。

穿越防火牆

大多數組織用防火牆保護網路。Java RMI、CORBA 的傳輸協定通常過不了防火牆,但 HTTP 與 SMTP 通常被放行——這正是用它們傳 SOAP 的一大方便之處。

💡
關鍵

SOAP 信封不含目的地,由 HTTP 等傳輸協定決定送往何處;HTTP/SMTP 還能穿越防火牆。

STEP 2

生活妙喻

信封內容 vs 寄送方式

寫信的人不該管郵差怎麼送

想像你寫好一封信(SOAP 信封),信的內容和「要用航空、海運還是宅配」是兩回事。SOAP 就是這樣:

  • 信的內容(SOAP 信封)裡沒有寫收件地址
  • 要寄去哪、用什麼方式,交給寄送系統(HTTP)處理。

這帶來彈性:今天用 HTTP、明天想換 SMTP 都行,信的內容不用改。但也有代價:你得懂每種寄送方式的規矩。

WS-Addressing:把地址貼回信封

問題來了:如果想讓信經過一連串轉運站,每站該往哪轉?早期做法是讓中介者邊轉邊改標頭,但這可能被竄改、危及安全

WS-Addressing 的解法:讓 SOAP 標頭自己帶路由資料(用一個叫 Endpoint Reference 的 XML 結構,含目的地址與路由資訊),底層基礎設施負責算『下一跳』,中介者不必亂改標頭。就像在信封上貼一張官方統一的轉運標籤,而不是讓每個轉運員各自塗改。

💡
關鍵

信的內容(SOAP)與寄送方式(傳輸)分離;WS-Addressing 把路由資訊放進標頭以脫離傳輸並更安全。

STEP 3

實用超能力

選對可靠傳遞語意

TCP 不夠可靠,所以有了 WS-ReliableMessaging

SOAP 常走 HTTP,HTTP 跑在 TCP 上。但 TCP 在惡劣情況下不保證一定送達:逾時就宣告連線斷掉,留下『我剛剛送的訊息到底收到沒?』的疑問。

為此,OASIS 提出 WS-ReliableMessaging,讓 SOAP 訊息能依不同語意傳遞:

語意 意思
At-least-once(至少一次) 至少送達一次;送不到會回報錯誤
At-most-once(至多一次) 至多送達一次;送不到回報錯誤
Exactly-once(剛好一次) 剛好送達一次;送不到會回報錯誤

搭配順序保證:

  • In-order(依序):同一個寄送者的訊息,依送出順序送達。
flowchart TD
  A[寄送者送出訊息] --> B{選擇語意}
  B --> C[至少一次 送不到回報]
  B --> D[至多一次 送不到不回報]
  B --> E[剛好一次 送不到回報]

重要提醒:WS-ReliableMessaging 講的是單一訊息的傳遞次數,不要跟第 5 章 RPC 的呼叫語意(指伺服器執行遠端程序的次數)搞混!

💡
關鍵

WS-ReliableMessaging 提供至少一次/至多一次/剛好一次與依序送達,講的是訊息傳遞而非程序執行次數。

🔆
生活妙喻:SOAP 與傳輸協定分離 ≈ 寫信內容 vs 選擇寄送方式

信的內容(SOAP 信封)不含地址也不管怎麼寄;要航空還是宅配(HTTP/SMTP)由寄送系統決定,內容不必改。

🔆
生活妙喻:WS-Addressing ≈ 信封上的官方轉運標籤

與其讓每個轉運員各自塗改地址(可能被竄改),不如貼一張統一格式的轉運標籤把路由資訊帶在標頭裡。

🔆
生活妙喻:可靠傳遞語意 ≈ 寄包裹時選的『送達保證』選項

就像寄件時選『必達會通知』『送不到就算了』等選項,WS-ReliableMessaging 讓你挑至少一次、至多一次或剛好一次。

本節字彙

endpoint(端點)
Web 服務的服務參考,指向服務可被接觸的位址;HTTP 標頭中會放端點位址。
🧠 endpoint=服務對外的『接觸點』。
WS-Addressing
把訊息路由資料放進 SOAP 標頭的規範,使定址獨立於底層傳輸並避免中介者竄改。
🧠 把『地址』Address 放進標頭裡。
WS-ReliableMessaging
OASIS 規範,提供 SOAP 訊息至少一次、至多一次、剛好一次與依序送達等可靠傳遞語意。
🧠 Reliable=可靠,挑你要的送達保證。
為什麼用 HTTP 或 SMTP 來傳輸 SOAP 訊息,在跨組織存取時特別方便?
SOAP 信封本身不含目的地位址。這個設計的直接後果是什麼?
早期讓中介者一邊轉送一邊修改 SOAP 標頭裡的路由資訊,被指出有什麼問題?WS-Addressing 如何改善?
03

Web 服務與分散式物件的差異

為何 Web 服務不能動態建立遠端物件、沒有 servant,以及 Java JAX-RPC 如何隱藏 SOAP 細節。

Web 服務 vs 分散式物件與 JAX-RPC

為何 Web 服務不能動態建立遠端物件、沒有 servant,以及 Java JAX-RPC 如何隱藏 SOAP 細節。

STEP 1

深度探秘

Web 服務沒有『動態建立遠端物件』

表面像 RMI,骨子裡很不同

表面上,Web 服務和 RMI(遠端方法呼叫)很像:客戶端都是『拿一個參考去呼叫遠端的操作』。RMI 用遠端物件參考,Web 服務用 URI。但類比到此為止。

關鍵差異:不能動態產生遠端物件

在分散式物件模型裡,物件可以動態建立新的遠端物件並回傳它們的參考。例如共享白板的 newShape 是個工廠方法:每呼叫一次就在伺服器產生一個新的 Shape 實例,回傳它的遠端參考。

Web 服務做不到這件事

一個 Web 服務實質上就是單一的遠端物件。因此垃圾回收與遠端物件參考都不適用。

所以課本把白板範例改寫成 Web 服務版(Figure 9.7):移除 Shape 介面、把它的操作併進 ShapeList,並讓 newShape 回傳一個整數(GraphicalObject 在向量中的位置),不再是工廠方法。

沒有 servant

分散式物件的伺服器是一堆 servant(潛在的遠端物件) 組成。Web 服務不支援 servant,無法隨需求動態產生它們。為了強制這點,Web 服務介面的實作不可有建構子或 main 方法

💡
關鍵

Web 服務等於單一遠端物件,不能像分散式物件那樣動態建立遠端物件或使用 servant。

STEP 2

生活妙喻

自助點餐機 vs 私人助理

兩種服務心態

  • 分散式物件像一位私人助理:你說『幫我新開一個專案』,他就生出一個專屬負責人(新遠端物件),還給你那個人的聯絡方式(遠端參考),之後你可以直接找那個人。需要幾個就生幾個。
  • Web 服務像一台自助點餐機:它就是那一台機器,不會因為你來點餐就『長出一台新機器』給你專用。你只能用它面板上既有的按鈕(操作),它回給你的是號碼牌或編號(整數),而不是一個新機器的『聯絡方式』。

這正對應到:

  • 分散式物件可動態建物件、回傳遠端參考;Web 服務不行,只能回傳像『編號』這種一般值。
  • 私人助理可以雇用更多人(servant);自助點餐機就是它自己,不生分身。
  • 既然點餐機就是單一機器,討論『要不要回收沒人用的助理』(垃圾回收)對它毫無意義。
💡
關鍵

分散式物件像會生分身的私人助理;Web 服務像就是它自己、只回傳編號的自助點餐機。

STEP 3

實用超能力

用 JAX-RPC 寫 Java Web 服務的規矩

JAX-RPC 幫你藏掉 SOAP

Java 開發 Web 服務的 API 叫 JAX-RPC,它把 SOAP 的細節對客戶端與服務端都藏起來,並把 Java 型別對應到 XML。允許的型別包括 Integer、String、Date、Calendar、java.net.uri、部分集合型別(如 Vector)、基本型別與陣列。

設計 Java Web 服務介面要遵守的規矩(Figure 9.7):

  • 介面必須 extends Remote
  • 不可有常數宣告(如 public final static)。
  • 方法必須擲出 RemoteException 或其子類別。
  • 參數與回傳型別必須是允許的 JAX-RPC 型別——特別是不能傳遞遠端參考
import java.rmi.*;

public interface ShapeList extends Remote {
    int newShape(GraphicalObject g) throws RemoteException;
    int numberOfShapes() throws RemoteException;
    int getVersion() throws RemoteException;
    int getGOVersion(int i) throws RemoteException;
    GraphicalObject getAllState(int i) throws RemoteException;
}

服務的實作沒有 main、沒有建構子,它被當成 servlet 跑在 servlet 容器(如 Tomcat)裡。容器內含分派器與骨架:請求進來,分派器找到對應骨架,把 SOAP 轉成 Java 呼叫對應方法,再把回傳值轉回 SOAP 回覆。客戶端則可用靜態代理、動態代理或動態呼叫介面三種方式呼叫。

💡
關鍵

JAX-RPC 隱藏 SOAP 細節;介面須 extends Remote、方法擲 RemoteException、不能傳遠端參考,實作無 main/建構子並跑在 servlet 容器。

🔆
生活妙喻:Web 服務不能動態建遠端物件 ≈ 自助點餐機不會長出新機器

點餐機就是它自己,不會因你來就生一台新機給你專用;它只回號碼牌(編號),而非新機器的聯絡方式。

🔆
生活妙喻:沒有 servant ≈ 店裡沒有可隨時加雇的臨時店員

分散式物件可隨需求生出 servant 來顧不同資源;Web 服務不行,所以實作不准有建構子或 main。

🔆
生活妙喻:servlet 容器 ≈ 替你接電話、轉接到正確分機的總機室

Tomcat 這類容器像總機室,把進來的 SOAP 請求分派給正確的骨架方法,再把結果包成 SOAP 回覆送出。

本節字彙

servant
分散式物件模型中代表伺服器資源的物件,可隨需求動態建立;Web 服務不支援。
🧠 servant=幫忙顧一份資源的『僕人』,Web 服務沒有。
JAX-RPC
Java 開發 SOAP Web 服務與客戶端的 API,對程式設計師隱藏 SOAP 與 XML 細節。
🧠 JAX-RPC=Java 版的『遠端呼叫』包裝。
servlet 容器
負責載入、初始化與執行 servlet 的環境(如 Tomcat),內含分派器與骨架。
🧠 裝 servlet 的『容器』,像總機室。
在分散式物件版的共享白板中,newShape 是工廠方法,每次呼叫會建立新的 Shape 並回傳遠端參考。改寫成 Web 服務版後,newShape 為什麼改成回傳一個整數?
為什麼課本說『垃圾回收與遠端物件參考對 Web 服務來說不相關』?
你要寫一個 Java Web 服務介面,下列哪一項違反了 JAX-RPC 的規定?

Web 服務 vs CORBA

命名、參考、啟動與位置分離、易用性與效率上的取捨,以及各自適合的場景。

STEP 1

深度探秘

為『一家公司』設計 vs 為『整個網際網路』設計

根本差異:使用情境

Web 服務與 CORBA 最大的差別是預期的使用情境。CORBA 是為單一組織或少數合作組織設計的,這讓它某些設計太過集中,不適合獨立組織間的隨意合作。

命名 (Naming) 問題

CORBA 每個遠端物件靠 Naming Service 命名,把名稱對應到位址(IOR)。但這個服務為組織內設計,不像 DNS 那樣全網際網路通用。不同組織要『聯邦』各自的命名服務並非自動發生——得先知道對方的初始命名情境,所以實際上把物件分享侷限在少數聯邦過的組織。

參考 (Reference) 問題

CORBA 的遠端物件參考叫 IOR,裡面的型別識別碼只有儲存該型別定義的介面儲存庫看得懂。這意味客戶端與伺服器得共用同一個介面儲存庫——在全球尺度上不切實際

相對地,Web 服務用 URL 識別服務,只需要 DNS,而 DNS 本來就為全網際網路設計,所以任何客戶端都能呼叫任何組織的服務。

💡
關鍵

CORBA 為單一/少數組織設計、依賴集中的命名服務與介面儲存庫;Web 服務用 URL 加 DNS,天生適合全網際網路。

STEP 2

生活妙喻

公司內部分機簿 vs 全球電話系統

兩種『找到人』的方式

  • CORBA 的命名/參考像一本公司內部分機簿:在公司內好用,但要打給別家公司,得先兩邊談好、互相交換分機簿(聯邦命名服務),而且分機號(IOR 型別識別碼)只有自家總機(介面儲存庫)看得懂。跨公司?麻煩。
  • Web 服務的 URL + DNS全球統一的電話/地址系統:每個服務有個全球唯一的『地址』(URL),靠舉世通用的 DNS 就能找到,不必事先跟對方總機談妥。

再看其他面向的取捨:

面向 CORBA Web 服務
易用性 大型複雜軟體,要安裝維護 HTTP/XML 已內建於常見作業系統,方便
效率 CDR 是二進位,較快 XML 是文字,較慢較肥
額外服務 內建交易、並行、安全、事件、持久物件 需另外疊加

效率上有個驚人的數字:研究指出 SOAP 請求訊息約是 CORBA 的 14 倍大,一次 SOAP 請求平均花掉約 882 倍的時間。

💡
關鍵

CORBA 像公司內部分機簿(強但封閉),Web 服務像全球地址系統(通用方便但較慢較肥)。

STEP 3

實用超能力

什麼時候選誰

選型決策

別誤會:CORBA 慢、肥,不代表它沒用。各有適合的舞台。

flowchart TD
  A{使用情境是什麼} --> B[組織內部或少數合作組織]
  A --> C[全網際網路 跨任意組織 隨意存取]
  B --> D[CORBA 內建交易並行安全等服務 適合複雜互動]
  C --> E[Web 服務 用 URL 與 DNS 全球可達 鬆耦合]

選 CORBA

  • 單一組織或一群相關組織內運作。
  • 需要很複雜的互動,並想善用內建的交易、並行控制、安全、事件、持久物件等服務。
  • 願意投入學習成本,享受分散式物件模型在複雜應用設計上的優雅。

選 Web 服務

  • 要跨全網際網路、跨任意組織、可隨意 (ad hoc) 存取而不事先安排。
  • 看重鬆耦合與互通性,能接受 XML 帶來的效能與訊息大小開銷。
  • 而且現實是:對許多應用而言,SOAP 的開銷其實感覺不太出來,加上頻寬、處理器、記憶體與磁碟都便宜,影響被淡化。

W3C 等也在研究把二進位資料塞進 XML(XML 已支援十六進位與 base64)以提升效率。

💡
關鍵

組織內部、需複雜互動且要內建服務選 CORBA;要全網際網路通用、鬆耦合、可隨意存取選 Web 服務。

🔆
生活妙喻:CORBA 命名 vs Web 服務 URL+DNS ≈ 公司分機簿 vs 全球地址系統

CORBA 像公司內部分機簿,跨公司得先互換才用得到;Web 服務像全球統一地址,靠通用的 DNS 人人可達。

🔆
生活妙喻:CDR vs XML 的效率取捨 ≈ 壓縮檔 vs 純文字檔

CORBA 的二進位 CDR 像壓縮檔,小而快;XML 像純文字檔,人讀得懂但體積大、處理慢。

🔆
生活妙喻:CORBA 內建服務 ≈ 全配豪華套裝 vs 自行加購配件

CORBA 像全配套裝,交易、安全、並行都內建;Web 服務像基本款,這些得另外疊加上去。

本節字彙

IOR
CORBA 的遠端物件參考,含型別識別碼,但該識別碼只有對應的介面儲存庫看得懂。
🧠 IOR=CORBA 物件的『身分卡』,得靠專屬儲存庫解讀。
CDR
CORBA 的外部資料表示法,採二進位編碼,比文字的 XML 更小更快。
🧠 CDR=CORBA 的『緊湊二進位』格式。
ad hoc 存取
不需事先安排、隨意臨時的存取方式;Web 服務比 CORBA 更適合這種存取。
🧠 ad hoc=『臨時、隨興』,不必先談好。
為什麼 Web 服務比 CORBA 更適合『任意兩家素未謀面的公司隔著網際網路互相呼叫服務』?
CORBA 的 IOR 為什麼不適合當作全網際網路通用的物件參考(不像 URL)?
研究指出 SOAP 請求約是 CORBA 的 14 倍大、慢約 882 倍。為什麼許多應用仍選擇 Web 服務?
04

服務描述與目錄服務

WSDL 如何把服務描述分成抽象與具體兩部分,涵蓋 types、message、interface、binding、service。

WSDL 服務描述

WSDL 如何把服務描述分成抽象與具體兩部分,涵蓋 types、message、interface、binding、service。

STEP 1

深度探秘

服務描述:介面+怎麼溝通+在哪裡

為何需要服務描述

客戶端要跟服務溝通,得先知道介面長什麼樣。但 Web 服務的『服務描述 (service description)』比一般 IDL 多包了兩件事:

  1. 介面:服務能做什麼。
  2. 怎麼溝通:例如用 SOAP over HTTP。
  3. 在哪裡:服務的 URI。

為了跨語言,服務描述用 XML 寫,常用的語言就是 WSDL (Web Services Description Language)

把 URI 寫進描述的影響

因為服務描述直接寫進 URI,省去了傳統中介軟體常見的獨立 binder 或命名服務。代價是:描述一旦發布給客戶端,URI 就不能再改(但 URN 機制可在參考層做間接轉址來換位置)。對照之下,binder 方式讓客戶端用名稱在執行期查參考,參考可隨時間改變,但所有服務都得多一層『名稱到參考』的間接。

WSDL 把服務描述切成抽象 (abstract)具體 (concrete) 兩部分(Figure 9.10):抽象講『是什麼/怎麼』,具體講『在哪裡』。

💡
關鍵

服務描述=介面+通訊方式+URI,用 WSDL 寫;把 URI 內嵌省去 binder,但 URI 從此固定。

STEP 2

生活妙喻

一份完整的『服務說明書』

WSDL 像一份產品服務說明書

把 WSDL 想成你買服務時拿到的完整說明書,分成兩大區塊:

抽象部分(是什麼、怎麼用)——像說明書前半的『功能與規格』:

  • types:定義會用到的資料型別。簡單型別(如 int)直接對應 XML;複雜的(如 GraphicalObject)就描述成一串具名欄位的 complexType。
  • message:描述交換的訊息。文件風格直接用這些訊息;請求-回覆風格則每個操作配兩個訊息(一請求一回覆)。
  • interface(有時叫 portType):把操作集合在一起。

具體部分(在哪裡、怎麼接觸)——像說明書後半的『安裝與聯絡方式』:

  • binding:用什麼協定與資料表示(如 SOAP、HTTP、MIME)。
  • service:服務名稱與一或多個端點(port)位址。
flowchart TD
  A[WSDL 服務描述] --> B[抽象部分 是什麼怎麼用]
  A --> C[具體部分 在哪裡怎麼接觸]
  B --> D[types 型別]
  B --> E[message 訊息]
  B --> F[interface 操作集合]
  C --> G[binding 協定與表示]
  C --> H[service 端點位址]

模組化的好處:同一個 interface 可搭配不同 binding 或位置重複使用,就像同一份功能規格可搭不同安裝方式。

💡
關鍵

WSDL 像服務說明書:抽象部分含 types/message/interface(是什麼),具體部分含 binding/service(在哪裡)。

STEP 3

實用超能力

訊息、操作模式與工具

訊息導向還是操作導向

客戶端與伺服器只需要對『要交換的訊息』有共識

  • 服務若只交換少數幾種文件 → WSDL 只描述各種訊息型別,服務看收到的訊息型別決定要做什麼、回什麼。
  • 服務若支援多種操作 → 較有效的做法是把訊息描述成帶引數的操作請求與對應回覆,讓服務據此分派。注意:WSDL 裡的 operation 是用來關聯請求與回覆訊息的構造,和服務介面定義的 operation 概念不同。

訊息交換模式(Figure 9.12)

每個 operation 要指定客戶端與伺服器間的訊息交換模式,常見如:

模式 說明
In-Out 最常用的請求-回覆;回覆可被 fault 取代
In-Only 單向訊息,maybe 語意,不送 fault
Robust In-Only 保證送達的單向,可送 fault
Out-In 由伺服器發起的請求-回覆

WSDL 2.0 還能自訂新模式、且 interface 支援簡單的繼承(B 可 extends A,但不可遞迴)。

工具與實務

完整 WSDL 可經 URI 直接取得,或透過 UDDI 目錄間接取得。有工具(如 WSDL4J)能用圖形介面產生 WSDL,免得人去碰繁瑣細節;也能從 Java JAX-RPC 等介面定義自動產生 WSDL。

💡
關鍵

WSDL 可訊息導向或操作導向,每個 operation 指定如 In-Out 的交換模式;工具能自動產生 WSDL,並可經 UDDI 取得。

🔆
生活妙喻:WSDL 抽象 vs 具體部分 ≈ 說明書的『功能規格』與『安裝聯絡方式』

抽象部分像規格頁講『能做什麼、用什麼資料』;具體部分像安裝頁講『用什麼協定、去哪個地址接觸』。

🔆
生活妙喻:把 URI 內嵌服務描述 ≈ 名片上直接印固定地址 vs 留一支總機分機

WSDL 把 URI 印死在描述上,省去總機(binder)但地址不能改;binder 方式像留分機,可隨時改轉接但每次都要多問一次。

🔆
生活妙喻:模組化的 interface 與 binding ≈ 同一份食譜可用瓦斯爐或電磁爐做

同一個 interface 像一份食譜,可搭配不同 binding(不同爐具/協定)或位置重複使用。

本節字彙

WSDL
用 XML 描述 Web 服務的語言,涵蓋 types、message、interface、binding、service 等元素。
🧠 WSDL=Web 服務的『說明書』語言。
binding
WSDL 具體部分中指定要用哪些訊息格式與外部資料表示(如 SOAP、HTTP、MIME)的區塊。
🧠 binding=把服務『綁定』到某個協定。
In-Out 模式
WSDL 操作的訊息交換模式中最常用的一種,即請求-回覆,回覆可被 fault 取代。
🧠 In 進來一個請求、Out 出去一個回覆。
Web 服務的『服務描述』比傳統 IDL 多描述了哪兩件事?
WSDL 把 URI 直接寫進服務描述,這帶來什麼取捨?
GraphicalObject 在 Java 裡由 int、String、boolean 組成。它在 WSDL 的 types 中通常如何被表示,好讓異質客戶端共用?

UDDI 目錄服務

UDDI 同時是名稱服務與目錄服務,其四種資料結構、查詢與發布 API,以及登錄處的複寫機制。

STEP 1

深度探秘

白頁與黃頁:兩種找服務的方式

客戶端怎麼找到服務

客戶端取得服務描述的方式很多——最常見的是有人做個網頁宣傳服務,你 Google 一下就找到。但組織若想有系統地讓客戶端找到服務,用目錄服務更方便。這就是 UDDI (Universal Description, Discovery and Integration) 的用途。

UDDI 同時是名稱服務也是目錄服務

  • 白頁 (white pages):按名稱查——例如以『提供服務的組織』來找。
  • 黃頁 (yellow pages):按屬性/類別查——例如找『旅行社』或『書商』這類服務。

當然,WSDL 描述也能透過 URL 直接取得,方便正在寫客戶端的開發者。

flowchart TD
  A[客戶端想找服務] --> B[白頁 按名稱或組織查]
  A --> C[黃頁 按類別屬性查]
  A --> D[直接用 URL 取得 WSDL]
  B --> E[找到 bindingTemplate 取得 WSDL 的 URL]
  C --> E
💡
關鍵

UDDI 同時是名稱服務與目錄服務:白頁按名稱查、黃頁按屬性類別查,也可直接用 URL 取得 WSDL。

STEP 2

生活妙喻

一本超強的工商電話簿

UDDI 就像工商電話簿

老式的電話簿正好有白頁(按人名/公司名查)和黃頁(按行業類別查)——UDDI 直接借用了這個比喻。

它用四種資料結構來組織內容(Figure 9.15):

結構 像電話簿裡的什麼 內容
businessEntity 公司的基本資料頁 提供服務的組織名稱、地址、業務等
businessServices 公司提供的一組服務 一組服務實例的名稱與用途描述(如旅行社、書商)
bindingTemplate 怎麼聯絡這項服務 服務實例的位址與服務描述的參考
tModel 詳細的服務說明書 通常是 WSDL 文件,存在資料庫外,用 URL 取得

大部分結構都用一個叫 key 的識別碼存取(tModel 例外,用 URL)。

搜尋流程也很像翻電話簿:先用 find_business 找到一堆符合的公司摘要,再用 find_service 縮小到你要的服務類型,最後拿到合適的 bindingTemplate 的 key,就能找到取得 WSDL 的 URL。手上已有 key 的人,可直接用 get_xxx 系列操作(如 get_BusinessDetail)拿到對應項目。

💡
關鍵

UDDI 像工商電話簿,用 businessEntity、businessServices、bindingTemplate、tModel 四種結構組織,多用 key 存取。

STEP 3

實用超能力

查詢、發布、訂閱與複寫

UDDI 的 API 與運作

查詢分兩套操作:

  • get_xxx(get_BusinessDetail、get_ServiceDetail 等):拿著 key 直接取回對應項目。
  • find_xxx(find_business、find_service 等):用搜尋條件取回一組符合的項目摘要(名稱、描述、key、URL),適合一步步縮小範圍的瀏覽。

此外還有 notify/subscribe(通知/訂閱) 介面:客戶端登記對某些項目感興趣,項目變動時就(同步或非同步)收到通知。

發布:第一次發布某資料結構時,它會拿到一個 URI 形式的 key(如 uddi:cdk5.net:213),而發布它的那台伺服器成為它的擁有者

登錄處與複寫

UDDI 基於複寫的資料:一個 registry(登錄處) 由一或多台 UDDI 伺服器組成,每台都有同一份資料副本,彼此互相複寫。

關鍵規則:

  • 對某資料結構的所有變更,都必須提交給它的擁有者(最初發布它的伺服器)。
  • 任何一台都能回應查詢與發布。
  • 複寫用一種向量時間戳 (vector timestamp) 決定哪些變更該傳播。比 Gossip、Coda 等方案簡單,因為:(1) 同一結構的所有變更都在同一台伺服器做;(2) 同一來源的更新會被依序收到,但不同來源間不強制排序。

與 X.500 不同:UDDI 的查詢由單一伺服器獨力回應,不需與其他伺服器互動。

💡
關鍵

UDDI 用 get_xxx/find_xxx 查詢、notify/subscribe 訂閱、變更須交給擁有者,登錄處用向量時間戳做簡化複寫。

🔆
生活妙喻:UDDI 白頁與黃頁 ≈ 電話簿的白頁與黃頁

白頁按公司名查、黃頁按行業類別查,UDDI 直接套用這個比喻:按名稱或按屬性找服務。

🔆
生活妙喻:四種資料結構 ≈ 公司在電話簿裡的層層資料

businessEntity 是公司基本頁、businessServices 是它的服務群、bindingTemplate 是聯絡方式、tModel 是詳細說明書(WSDL)。

🔆
生活妙喻:變更須提交給擁有者 ≈ 只有原作者能改自己的條目

資料結構由最初發布的伺服器擁有,要改它就得回去找原擁有者,這讓複寫變得簡單。

本節字彙

UDDI
Web 服務的目錄服務,兼具名稱服務(白頁)與目錄服務(黃頁),讓客戶端查找服務描述。
🧠 UDDI=Web 服務版的工商電話簿。
tModel
UDDI 四種資料結構之一,存放服務描述(通常是 WSDL),放在資料庫外、用 URL 取得。
🧠 tModel=放在外面、用網址拿的『說明書』。
registry(登錄處)
由一或多台持有相同資料副本的 UDDI 伺服器組成,彼此複寫資料。
🧠 registry=一群同步副本的『登錄站』。
一位開發者只知道想要『某家特定公司提供的服務』,另一位則想找『任何一家旅行社服務』。他們分別該用 UDDI 的哪種查找方式?
在 UDDI 的四種資料結構中,實際存放 WSDL 服務描述(位於資料庫外、以 URL 取得)的是哪一個?
客戶端手上已經有某個項目的 key,想直接取回該項目。應該用哪一類操作?
05

安全、協調與應用

為何 TLS 不夠用、XML 安全如何對文件局部簽章或加密,以及 KeyInfo 與標準化 XML 的作用。

XML 安全

為何 TLS 不夠用、XML 安全如何對文件局部簽章或加密,以及 KeyInfo 與標準化 XML 的作用。

STEP 1

深度探秘

把保護綁在文件裡,而不是通道上

為什麼 TLS 不夠用

XML 安全是一組 W3C 設計,用於簽章、金鑰管理與加密。它瞄準的情境是:一份文件被建立、交換、儲存、再交換,過程中可能被一連串不同的人修改。

經典例子是病患的醫療紀錄:診所、診間、醫院都會用到它;醫師、護理師、顧問、行政、藥師各自增修不同部分。我們需要保證『某段治療建議確實出自某人之手、且沒被竄改』。

這種需求 TLS(舊稱 SSL)滿足不了。為什麼?

TLS 建立的是一條安全通道,保護的是傳輸過程

但通道只在傳輸當下有效。文件一旦存下來,離開了通道,就失去保護;而且 TLS 沒辦法做到『只簽/只加密文件的某一部分、且讓不同角色看不同部分』。

解法:把安全寫進文件本身,當成文件的屬性而非通道的屬性。XML 這種結構化、可放 metadata 的格式正好做得到——用特殊標籤標記哪段是加密/簽章的資料、以及簽章本身。

💡
關鍵

TLS 保護的是傳輸通道,文件存下來就失去保護;XML 安全把保護綁進文件本身,可局部簽章或加密。

STEP 2

生活妙喻

防彈運鈔車 vs 文件上的火漆封印

兩種保護思維

  • TLS 像一台防彈運鈔車:錢在『車上(通道中)』很安全,但錢一下車存進倉庫,運鈔車就保護不到了;而且運鈔車是『整車一起保護』,沒辦法只保護其中一個袋子、讓不同人看不同袋。
  • XML 安全像在文件本身蓋火漆封印與簽名:保護跟著文件走,不管它被存到哪、轉給誰都還在;而且可以只在某幾段蓋封印(加密)或簽名,其他段落留白讓人能修改。

這對應到 XML 安全的基本能力:

  • 可只加密整份或部分內容:例如金融交易中只藏卡號,外人能看出這是筆交易卻看不到卡號;甚至連『是訂單還是付款』都藏起來。
  • 可只簽章整份或部分內容:關鍵段落簽名以保證來源與未竄改,其他段落不簽好讓人增修。
  • 層層接力:Alice 簽了傳給 Bob,Bob 加註『見證簽名』再簽整份;也能對已加密的文件再加內容並加密。
💡
關鍵

TLS 像運鈔車只保護運送途中;XML 安全像文件上的火漆封印,保護跟著文件走且能只保護局部。

STEP 3

實用超能力

演算法、找金鑰與標準化 XML

預先簽好的文件如何被未來的人驗證

XML 文件常在還不知道誰會收的情況下就被簽章或加密。既然原作者可能早已不在線上協商,就需要規則:

  • 標準須規定一套必備演算法:至少一種加密、一種簽章演算法為強制,以求最廣互通;其餘為選用。
  • 所用演算法的名稱要寫進文件本身:用 XML 元素指定簽章或加密所用演算法的 URI,且通常巢狀在含『簽章資訊』或『加密資料』的元素裡。

找金鑰:KeyInfo

KeyInfo 元素用來指出『驗章或解密該用哪把金鑰』,可含憑證、金鑰名稱等。它是選用的(簽署者也許不想對所有人透露金鑰資訊)。妙處在於:只要 KeyInfo 沒被加密綁進簽章本身,就能在不破壞簽章的情況下補資訊——Alice 只放金鑰名稱,Bob 收到後查到驗章所需資訊,補進 KeyInfo 再轉給 Carol。

標準化 XML (Canonical XML)

同一份『邏輯上相同』的 XML,可能有不同寫法(屬性順序、字元編碼不同)。為了讓簽章可靠,要先把 XML 標準化 (canonicalize):產生唯一的標準序列化(補上預設屬性、屬性與 schema 宣告按字典序排、統一換行、用 UTF-8)。

flowchart TD
  A[原始 XML 可能有多種等價寫法] --> B[標準化成唯一形式]
  B --> C[對標準形式簽章]
  C --> D[驗章時再標準化後比對]

標準形式含祖先情境(命名空間、屬性值),所以同一元素被放到不同情境時簽章會驗不過。若想讓簽好的元素能用於不同情境,可用 Exclusive Canonical XML(省略情境)。

💡
關鍵

演算法名稱寫進文件、KeyInfo 幫忙找金鑰且可不破壞簽章地補充、標準化 XML 讓等價文件有唯一形式以利驗章。

🔆
生活妙喻:TLS vs XML 安全 ≈ 防彈運鈔車 vs 文件火漆封印

TLS 只保護運送途中(通道),下車存倉就失效;XML 安全把封印蓋在文件上,保護跟著文件走,還能只保護某幾段。

🔆
生活妙喻:局部簽章/加密 ≈ 只在合約關鍵條款蓋章

可只在關鍵段落蓋章或加密以保證來源與機密,其他段落留白讓人增修,整份文件靈活協作。

🔆
生活妙喻:標準化 XML ≈ 把不同手寫體謄寫成統一印刷體再比對

等價但寫法不同的 XML 先謄成唯一標準形式,簽章才能可靠比對,避免因排版差異誤判被竄改。

本節字彙

XML 安全
一組用於對 XML 文件局部或整份簽章、加密與金鑰管理的 W3C 設計,把保護綁在文件本身。
🧠 把『鎖』直接做進文件裡。
KeyInfo
XML 安全中用來指出驗章或解密所需金鑰(如憑證、金鑰名稱)的選用元素。
🧠 KeyInfo=『金鑰的線索』。
Canonical XML(標準化 XML)
把邏輯相同但寫法各異的 XML 轉成唯一標準序列化形式,供數位簽章可靠比對。
🧠 canonical=『正典/標準』,唯一的官方寫法。
一份醫療紀錄會被存檔、轉交、由多位人員陸續增修。為什麼用 TLS 保護傳輸並不足以滿足需求?
在一筆金融交易紀錄中,想讓外人能辨識『這是一筆交易』卻看不到信用卡卡號。XML 安全的哪項能力支援這件事?
Alice 簽署文件時 KeyInfo 只放金鑰名稱;Bob 收到後查到驗章所需資訊並補進 KeyInfo 再轉給 Carol,且沒破壞 Alice 的簽章。這之所以可行是因為?

Web 服務的協調與編排

為何單一請求-回覆不夠、長交易為何不適合兩階段提交,以及 choreography 描述合作流程的用途。

STEP 1

深度探秘

單一請求-回覆不夠用

為什麼需要協調

SOAP 基礎設施只支援單一請求-回應。但很多有用的應用需要好幾個請求依特定順序完成。例如訂機票:要先查價格與空位,才能訂位。

透過瀏覽器操作時,瀏覽器(依伺服器提供的資訊)幫忙控制操作順序。但如果是一個 Web 服務(如旅遊代理服務)在向其他服務訂位,它就需要一份描述,告訴它跟租車、旅館、機票等服務互動時該照什麼步驟走(Figure 9.18 的旅遊代理情境)。

還有另一個問題:伺服器同時面對多個客戶端時要維持資料一致性。經典例子是銀行轉帳——存入與提出必須都做。第 17 章用兩階段提交 (two-phase commit) 協定讓合作的伺服器確保交易一致。

所以協調有兩個面向:

  1. 給『當客戶端的 Web 服務』一份互動協定該怎麼走。
  2. 在多客戶端下維持資料一致性
💡
關鍵

SOAP 只管單次請求-回應;多步驟、有順序的任務與多客戶端一致性,都需要額外的協調機制。

STEP 2

生活妙喻

婚禮統籌 vs 一桌人各做各的

協調像一場有腳本的合作

想像辦一場婚禮,要協調場地、餐飲、攝影、花藝多家廠商。如果每家各做各的、沒人統籌,場面會亂掉。Web 服務的協調就是給大家一份共同腳本,規定誰先做什麼、什麼條件下換誰。

長交易為何不適合兩階段提交

兩階段提交像『大家舉手表決、全體同意才一起執行』——對交易很好。但旅遊代理這類任務耗時很長,用兩階段提交得長時間鎖住資源(例如一直占著座位不放),很不實際。

替代方案:用較寬鬆的協定,每個參與者邊發生邊改自己的持久狀態;萬一失敗,再用應用層的協定把動作復原(補償)

這就像婚禮各廠商先各自照常準備,若臨時取消,再各自退訂、退款收尾,而不是讓全部廠商在簽約前都僵在那裡互相等待。

課本提到 WS-Coordination:一個類似分散式交易模型、有協調者 (coordinator)參與者 (participant) 角色、能演出特定協定(例如執行分散式交易)的通用協調模型。

💡
關鍵

協調像給合作廠商一份共同腳本;長交易不適合鎖資源的兩階段提交,改用寬鬆的補償式協定。

STEP 3

實用超能力

編排 (choreography):描述合作的全景

什麼是 choreography

試想:把一群 Web 服務合作(如旅遊代理情境)中,所有可能的有效互動路徑都描述出來。這份描述就能拿來協調共同任務,也能當作規格讓新加入的服務(如新的訂票服務)遵循。

W3C 用 choreography(編排) 一詞,指一種以 WSDL 為基礎、用來定義協調的語言。它規範訊息交換的順序與條件,提供整組互動的全景描述,展現每個參與者的行為,以增進互通性。

編排描述能拿來做什麼

一份編排描述像是參與者間的合約,可用於:

  • 為想加入的新服務產生程式碼骨架
  • 為新服務產生測試訊息
  • 促進對這場合作的共同理解
  • 分析合作,例如找出可能的死結 (deadlock)
flowchart TD
  A[編排描述 全體互動腳本] --> B[產生新服務的程式碼骨架]
  A --> C[產生測試訊息]
  A --> D[促進共同理解]
  A --> E[分析找出死結]

編排語言期望具備:階層與遞迴組合、加入新服務、並行/替代/重複路徑、可變逾時、例外處理、非同步回呼、參考傳遞、標記交易邊界、可含人類可讀文件等特性。最終目標是做出一個宣告式、以 XML 為基礎、可用 WSDL 定義的編排語言(W3C 已對 WS-CDL 提出建議)。

💡
關鍵

choreography 用 WSDL 為基礎描述全體互動的順序與條件,像合約,可產生骨架、測試、促進理解與分析死結。

🔆
生活妙喻:Web 服務協調 ≈ 婚禮統籌給各廠商的共同腳本

多家服務合作就像多家婚禮廠商,需要一份共同腳本規定先後與條件,否則各做各的會亂套。

🔆
生活妙喻:長交易不用兩階段提交 ≈ 別讓所有廠商簽約前都僵著互等

兩階段提交會長時間鎖資源,像讓所有廠商在表決前都不能動;長任務改用先各自進行、失敗再補償退訂的寬鬆方式。

🔆
生活妙喻:choreography ≈ 一齣舞劇的全體走位腳本

編排像舞劇腳本,寫清每個舞者(服務)何時該做什麼動作、彼此如何配合,新舞者照腳本就能加入。

本節字彙

two-phase commit(兩階段提交)
讓合作伺服器確保交易一致的協定;適合短交易,但長交易會長時間鎖資源故不適用。
🧠 先全體表決、再一起提交,分兩階段。
WS-Coordination
類似分散式交易模型、含協調者與參與者角色、能演出特定協定的通用 Web 服務協調模型。
🧠 Coordination=協調,安排大家的角色與步驟。
choreography(編排)
以 WSDL 為基礎、描述多個 Web 服務間互動順序與條件的語言,提供合作的全景描述。
🧠 choreography=舞蹈『編排』,安排全體走位。
當『人』用瀏覽器訂機票時順序由瀏覽器掌控;但若改由一個旅遊代理 Web 服務自動向其他服務訂位,它額外需要什麼?
旅遊代理這類『耗時很長』的任務,為什麼不適合用兩階段提交來保證一致性?
長交易改用『較寬鬆的協定』時,參與者如何處理狀態與失敗?

SOA、Grid 與雲端

Web 服務作為 SOA 的主要實現方式、支撐 Grid 大規模資源共享,以及雲端如 AWS EC2 的角色。

STEP 1

深度探秘

SOA:用鬆耦合服務組積木

服務導向架構 (SOA)

Web 服務如今是分散式系統的主流範式之一。第一個大舞台是 服務導向架構 (Service-Oriented Architecture, SOA)

SOA 是一套設計原則:用一組鬆耦合、可被動態探索、能彼此溝通或透過編排協調的服務,來建構分散式系統。

SOA 是個抽象概念,可用多種技術實現(包括第 8 章的分散式物件或元件式做法),但主要實現方式是 Web 服務——正因為它天生鬆耦合。

SOA 最大的價值在廣闊的網際網路

  • 提供服務的共同視角,讓服務全球可達、便於後續組合。
  • 超越網際網路的異質性:A 公司內部用 CORBA、B 公司用 .NET,但兩者都用 Web 服務對外開放介面,就能全球互通。這就是 企業對企業 (B2B) 整合
  • 鼓勵 mashup:第三方開發者把兩個以上現有服務組合成新服務(如 JBidwatcher 串接 eBay 自動代標)。
💡
關鍵

SOA 用鬆耦合、可動態探索的服務組積木,主要靠 Web 服務實現,促成 B2B 整合與 mashup。

STEP 2

生活妙喻

Grid 像全球共用的超級實驗室

Grid:大規模共享資源

Grid(網格) 指的是讓檔案、電腦、軟體、資料、感測器等資源能超大規模共享的中介軟體。典型使用者是不同組織的科學家團隊,合作解決需要大量電腦的問題——靠共享資料或共享運算力。

把它想成一座全球共用的超級實驗室:各國團隊把自己的儀器、資料、算力都接上來,彼此借用。課本舉的例子是『World-Wide Telescope』——把全世界的天文檔案整合成一個巨大資料庫。

為什麼不能把資料全搬到使用者本機?因為天文資料動輒TB、PB 級,傳輸時間與磁碟都吃不消。所以原則是:資料在它被收集與儲存的地方就地處理,科學家查詢時各地資料庫分析、必要時產生視覺化,再把結果送回。資料分散在多站處理,天生帶來平行性

由此推導出 Grid 應用的需求:遠端存取資源、就地處理、動態建立服務實例處理所需資料段、用 metadata 描述資料與服務特性、基於 metadata 的目錄服務、以及管理查詢與資源預約的軟體。

Web 服務能滿足前兩項(方便存取遠端檔案上的操作),其餘交給 Grid 中介軟體。標準是 OGSA,由 Globus 工具組實作,且 OGSA 建立在 Web 服務之上。

💡
關鍵

Grid 讓不同組織大規模共享資源、就地處理巨量資料;OGSA 與 Globus 以 Web 服務為基礎滿足這些需求。

STEP 3

實用超能力

雲端:一切皆服務,以 AWS 為例

雲端運算與 Web 服務

雲端運算是一組網際網路上的應用、儲存與運算服務,足以支應多數使用者需求,讓他們幾乎不必在本機存資料或裝軟體。它推廣『一切皆服務』的觀點——從基礎設施到軟體,常按使用量付費而非買斷。

Grid 與雲端的關係:Grid 先出現、是雲端的重要推手,兩者都想『把資源放在網際網路上提供』。差別在於 Grid 偏向高階、資料重或運算貴的應用,雲端更通用,並有獨特的商業模式。可以說 Grid 是雲端的早期形態。

既然『一切皆服務』,Web 服務正是雲端的自然實現路徑。最著名的例子是 AWS (Amazon Web Services)

  • AWS 用前面講過的 Web 服務標準對外提供,熟悉 Web 服務的程式設計師可直接上手、做 mashup。
  • Amazon 也採 REST 風格。
flowchart TD
  A[一切皆服務的雲端] --> B[用 Web 服務標準對外提供]
  B --> C[EC2 彈性運算 虛擬機器]
  B --> D[S3 物件儲存]
  B --> E[SQS 訊息佇列]

聚焦 EC2(彈性運算雲):『彈性』指運算容量可依需求伸縮。它給你的不是實體機器,而是一台虛擬機器(稱 instance),可選標準型、高記憶體型、高 CPU 型、叢集運算型等規格。EC2 建在 Xen hypervisor 上,可跑 Windows Server、Linux、OpenSolaris 等。它還有個聰明設計:彈性 IP 位址綁在你的帳號而非特定 instance,虛擬機器掛掉時可把 IP 重新指派到另一台,不必勞煩網管。

💡
關鍵

雲端把一切視為服務、按用量付費,用 Web 服務標準與 REST 實現;AWS EC2 提供可伸縮的虛擬機器與彈性 IP。

🔆
生活妙喻:SOA 與 mashup ≈ 用現成樂高積木拼出新玩具

SOA 把功能做成鬆耦合的服務積木,mashup 就是第三方把幾塊現成積木拼成新玩具(如串接 eBay 的自動代標)。

🔆
生活妙喻:Grid ≈ 全球共用的超級實驗室

各國團隊把儀器、資料、算力接上同一座虛擬實驗室互相借用,且因資料太大而採『就地處理、只送結果』。

🔆
生活妙喻:EC2 的彈性與彈性 IP ≈ 可隨時換大小的出租辦公室與不換的公司專線

instance 像可依需求換大小的出租辦公室;彈性 IP 像綁在公司名下的專線號碼,搬到哪間辦公室都能沿用。

本節字彙

SOA(服務導向架構)
用一組鬆耦合、可動態探索、能彼此協調的服務來建構分散式系統的設計原則,主要以 Web 服務實現。
🧠 把系統拆成一個個可組合的『服務積木』。
Grid(網格)
讓檔案、運算、資料等資源超大規模跨組織共享的中介軟體,常用於科學協作,OGSA/Globus 以 Web 服務實作。
🧠 Grid=把全球資源接成一張『大電網』共用。
EC2
AWS 的彈性運算服務,提供可依需求伸縮、稱為 instance 的虛擬機器,建於 Xen hypervisor 上。
🧠 EC2=Elastic(彈性)的雲端運算。
SOA 可用多種技術實現,但課本指出其『主要』實現方式是 Web 服務。最主要的原因是什麼?
A 公司內部用 CORBA、B 公司內部用 .NET,卻能在網際網路上互通合作。SOA 如何促成這件事?
World-Wide Telescope 這類 Grid 應用中,為什麼不把資料全部傳到使用者本機再處理?