個人經驗談現實中的 SOA, part 2 - 訊息、訊息、訊息
本系列文章–個人經驗談現實中的 SOA– 最初發佈在台灣PHP聯盟討論區,所以也有在討論區的網友們回應他們的看法。本文整理了我與網友的對談內容,並藉此做個結論。
謝謝 tokimeki, robmlee 兩位網友的回應。
回應之一
我個人是覺得,如果沒有「標準」,你得定一個出來。假設目前的現行架構不變,你可以獲得內部資源的協助作為前提,最快的方式是另外弄一台Application Server,透過這台AP去實做上述的任務,並提供統一的接口對外服務。
當然,實作上如果趕著上線的話,初版不要提供太多的服務,因為你必須去hack收到的HTML,把有用的資訊「抽」出來,轉換成你要的格式。之後就得開會跟其他小組的人協調,要求他們撰寫Interface文件,大家根據文件來寫程式。
tokimoki (HACGIS) 於 台灣PHP聯盟 回應內容之一
說到標準, SOAP, XML, JSON, HTTP, REST, ATOM 等就是標準。SOA 訊息驅動的基礎,就建立在這些訊息格式與傳送的標準之上。由於目前我所面對的絕大多數電子商務平台的管理資訊系統不提供這些內容,因此我們不得不去 hack html (這些 HTML 文件甚至不是 格式良好的 (well-formated) ,因此將這些文件交由 XML DOM 類別庫處理時往往會失敗) 。這種作法是不得已的,不能視為 SOA 的作法。至於小組協調、介面文件等事。嚴格來說,這是企業內的作法。我和對方是不同公司時,也就不能小組協調。再者, tokimeki 希望所有服務元件都能像 Google 那樣提供為各種開發工具所包裝好的 Google API ,讓程序員在自己程式中使用。亦即我前文的第二個程式碼部份所示。
現實中,即便如 PCxxxx 這種規模的公司,也無法為每個程序員準備好 PCxxxx API 或類別庫。所以一個可查詢的 WSDL 或是明確的公開資訊反而更重要。我們把這些外顯的、公開的功能當作介面 (interface) ,藉此把對方的系統當作一個服務 (service) 封裝在類別中使用。舉個例子,部落格的「引用 (trackback)」就是一種公開行為,任何人都可以透過引用網址,將訊息發佈在對方的系統上。再舉一例,現在的 digg, Hemidemi, myShare 等共享書籤服務,都會告訴你,只要在自己的網頁上加上像 xxx.com/bookmark/new?url=abc
這類 URL 或是 javascript code 就可以進行加入書籤的動作。這其實也是一種 SOA ,那些 URL 就是這個服務的公開行為 (public method)。說到這裡,大概有人已經拍桌道「Ruby on Rails 就是這樣實作的」。是的,而 CakePHP 、 Code Igniter 等 framework 也是採用這種實踐概念 (Framework of PHP5)。在現實中,對方的資訊系統只提供這類資訊的情形,比提供如同 Google API 這類完整類別庫的情形更常見。
回應之二
我看下來覺得這是個大麻煩,因為PCxxxx的開發人員不一定會去生出你要的東西,而用Hack網頁的HTML的方式,在PCxxxx改版時你們也要跟著改,這會是很大的麻煩。我個人覺得比較可行的方法是,雙方還是要談出一套標準,但模式改用「推」的方式來實做。請PCxxxx那邊更新資料時,也把同一份資料「推」給你們,你們提供一個標準以及寫好的程式模組給他們,請他們把這個模組放到他們的程式中。
tokimoki (HACGIS) 於 台灣PHP聯盟 回應內容之二
光看一個 PCxxxx 的例子就覺得這會是個大問題,但實際情況更糟。實際情形是我一個人要面對至少 5 個不同的電子商務管理資訊系統。全部都要自己 hack html ,真的是大麻煩。而提供程式模組互相植入的作法在實務上也被認為不可行。例如一個 PCxxxx 就有上百個像我方這樣的合作廠商。要每個廠商都把自己的模組推給 PCxxxx 植入,對雙方而言都是不可能的事。雙方都會感覺自己的資訊系統被注入 (inject) 、被暴露了。就像是一個類別被迫將私有或保護 (private/protected members) 成員開放為公開成員 (public members) 一般。在個體導向技術中,當一項軟體功能被迫要解除成員保護權限或是將使用關係變成繼承關係才能完成時,往往是這兩個類別的實例之間沒有交換足夠而良好的訊息所致。
我們在現實中有一個既有而簡便的實踐途徑,我們傾向先做到資料格式可用 XML/JSON 這類結構化文件進行交換。因為一份 XML 文件本身可自我描述,我即不需要去 hack ,也不需要 對方告訴我這份文件如何解讀。如此一來,雙方便可將彼此視為黑盒子。雙方的服務元件之間的關係維持在「使用關係」而非「繼承關係」。對方不需要知道我在幹嘛,我也不需要知道對方在幹嘛,我們純粹透過資料交換進行協同作業,讓資料自己說話。
回應之三
在台灣,廠商通常很弱勢,我想你會去hack HTML也是不得已的作法。人都是很自私的,誰要為了你把工作負擔加重?能談是最好,不能談就硬著頭皮接下,難不成要跟自己的荷包過不去?既然連談都不能談,別想要對方吐JSON/XML這些中介資料出來,這跟要求對方把資料推給你沒啥差別。我之所以說沒啥差別,是因為不管你用什麼資料交換技術,你還是得去針對特定廠商、服務去解析這些資料,轉成程式語言的資料結構再做進一步處理,即便用BizTalk之類的工具也不會輕鬆到哪裡去。既然如此,我個人就傾向讓客戶自己決定要吐什麼東西出來,當然啦,也必須確認這些資訊是否足夠讓我們處理,這就需要雙方協調。
tokimoki (HACGIS) 於 台灣PHP聯盟 回應內容之三
唉,我們可以說 SOA 是個被炒作的名詞 (或者說是另一個新瓶裝舊酒的名詞。從前文可知, 1994 年時的舊書就已經提到分散式個體導向系統架構) ,但我想我們還是要承認 XML 這種早在 6,7 年前就出現的結構性文件格式,現在已經是很成熟的應用技術。然而現實上,許多線上資訊系統之作業方式還是「人工導向」的。我們依賴「人」作為線上資訊系統之間的訊息匯流排,由人把資料從 A 系統複製出來,再貼到 B 系統去。從資料的觀點來看,對方現在丟出給我們的資料確實足夠讓我們進行下一步作業,但那是指人工作業的情形。如果要用資訊系統自動接手處理,則資訊內容的「格式」—僅僅是格式—,需要的是 XML 而不是 HTML 。
再說到程式修改,以我的經驗,在 MVC 架構下要增加一種資料輸出格式,只要加一個 View 就搞定。我先前在一間資訊公司作入口網站專案時,一開始只輸出 HTML 跟 JSON 兩種格式,其中 JSON 還是我個人為了方便用 Ajax 處理前端使用者介面而偷加的。當客戶說要加 RSS 格式時,我不過花了幾分鐘加了 View 就搞定。而 XML 式的正統做法是後端一律輸出成 XML 格式,再依使用者需求調用不同的 XSLT 轉換為前端的呈現內容。
如果對方的資訊架構是好的,那麼加一個 XML 格式其實對雙方有利。我們方便使用,他們也方便內部實踐 SOA 。如果對方的資訊架構就有問題,那麼這種需求自然就變成很大的軟體需求變更工作。
一切都在訊息
「封裝性 (encapsulation) 、繼承性 (inheritance) 、動態繫結 (dynamic binding)」是個體導向技術中廣為人知的三根支柱,然而這僅僅是個體導向技術的皮骨。徒有骨架不足為生命。個體導向的血肉是訊息。訊息聯繫這些骨架,並賦予個體生氣,這才構成我們所熟悉的個體導向世界。 再者,在源碼與類別庫 (source/library) 層次上的個體導向編程技術中,封裝性不過是張薄紙,程序員可以一戳就破,輕易打破個體的封裝隔離。但在分散式個體導向系統架構中,封裝性建立在軟體與系統 (software/system) 層次之上,堅固如銅牆鐵壁。鬆散耦合的程度如同各行其事、互不相識。
現實狀況就是如此,資訊系統滿山遍野,如果要透過傳統程序導向的觀念協同作業,則我們會有修改不完的程式工作,以及一切在個體導向技術中常見之伴隨打破封裝性而來的無止盡錯誤。唯有貫徹訊息驅動,透過資料交換而聯繫各個系統之協同作業。
……完全忽略 IT 環境中的另一個重要部分—資料,而這份資料也就是這些服務與應用程式要提供的資訊來源。
我們比較關切資料架構:瞭解跨系統資訊來源、關係以及含意的人,與能夠建構可重複使用服務,而應用程式開發人員也能夠找到並使用這樣的服務,不需要經過任何分析過程來了解這些關係。
SOA 及資訊服務,IBM developerWorks Live! 2006 © Bloor Research 2006
十年前談這些事或許還是在唱高調。因為當時的實踐途徑,如 CORBA 、 SOM 等,都不是從既有實務技術中發展的,既昂貴又複雜,離我太遙遠。但 SOA 不一樣, SOA 是我目前所知的分散式個體導向系統架構中最接近我的一種,它的一切都建立在我所熟知的既有實務技術與工具之中,例如 HTTP, XML, JSON, REST 等等。這些都是我在設計 Web application 時就熟悉的事物。而且我用 PHP 就可以快速實踐。我敢說對於以 Web programming 為主要開發環境的程序員而言, SOA 採用的根本是強迫上車策略。當我們還不知道這名詞、甚至還沒開始學習它的時候,我們就已經坐在這列車上了。