論壇文章
從原理面探討服務導向架構(SOA)

服務導向架構(Service-oriented Architecture,簡稱SOA)近兩年在企業軟體界被炒得火熱。像過去初期的物件導向(Object-oriented)程式、設計、分析一樣,現在的SOA是個模糊的名詞,也常被歸類為炒作詞(buzzword)。有些犬儒的人,更視它為大型軟體公司推銷蛇油(snake oil)的另一次嚐試。一個比較持平的見解是:SOA是一種架構風格(architectural style),不是一種產品,也不是一組定型的解決方案;它是讓我們在分析設計系統時,能夠循序漸進遵循的精神與原則(principles)。如果我們能依據這些原則導入,不但阻礙較小,也比較容易設計出有彈性而易重用(reusable),更符合商業價值(business value)的系統。SOA把產品與應用程式造成的邊界完全抹去,讓我們用服務的觀點來看待整個企業裡資訊系統的組合。本文將探討如何找出SOA的某些設計限制(constraints)與指導路線(guidelines),還有它們根據的軟體工程原理。

從凝聚力與連結力開始

軟體系統不管大小,有兩個維度可以用來做初步判斷好壞的準則:凝聚力(cohesion)和連結力(coupling)。凝聚力表示在一個邏輯單位(如module或package)內,各組成單位(如class)彼此間的依靠程度(dependency);連結力表示在不同邏輯單位間組成單位的依靠程度1。好的系統通常有高凝聚力及低連結力,而最糟的系統有低凝聚力與高連結力。我們做大系統的準則,就是想辦法把它切成一群子系統,使得子系統之間得連結力變得很小,但是在子系統內的凝聚力變大。如果每個子系統的凝聚力大,表示整個系統抽象切割合理;如果子系統間的連結力鬆(loose),表示設計上封存(encapsulation)的工夫做得好。

具體而言,我們在實踐SOA中,如果能利用以上兩種量度(metrics)來看看我們做得好不好,這樣會有個好的起點。首先要把相關子系統內的凝聚力增高,我們可以努力把子系統的邊界(boundaries)明顯切割好,也要努力讓子系統能夠有自主性(autonomous),不會因為內部製作細節的改變,而影響了服務本身的正確性。熟悉物件導向的讀者一眼就會看出,這跟我們使用介面(interface)而不是類別(class)來作為對外契約(contract)的原則很類似。

SOA的取捨、原則、門派

從以上觀點來看,大家可能會開始懷疑到底SOA有什麼新意,畢竟過去基於RPC(Remote Procedure Call)如CORBA或是DCOM這類的分散系統的技術都有辦法達到這樣的要求。比方說,CORBA用IDL來當對外契約,也沒有限制是何種程式語言或是作業系統。

SOA真正有別於CORBA和DCOM是在於它對低連結力上的積極態度。首先,理論上我們希望能利用文件傳遞(document-passing) 而不是程序呼叫(procedure call)的方式來做;這樣可以減低了在很多因需求變動時,需要改動的可能性。原因是我們把複雜的資訊藏在文件裡,而不是暴露在程序的外在簽型(signature)。這種用文件傳遞的作法,常常需要像型態(type)的詮釋資料(metadata)如XML Schema之類的機制來確保文件符合基本要求2;這樣的好處是:我們可以把schema當作契約,由schema上的彈性與版本控制,達到前後相容的目的。
SOA也對所謂的服務,有了一個精神上的指導:強調抽象(abstraction)、可組性(composability)、可重用性(reusability),這些在過去的框架底下雖然都有提出來,但是沒有被提升到一級的地位。

真正在介面如何設計上,各派的爭議很大。過去RPC及傳統企業軟體的那派,主張明白地訂好契約,以避免混淆。這派以現有SOAP這種訊息表示法為底,加上WSDL這種XML的web services(XML)描述語言,上面再架上各種WS-*的標準,又有W3C的加持,儼然成為主流派。反對者批評這種做法使得系統太僵硬,容易造成企業在快速服務變化要求下的阻力。另外也有人批評這種作法容易誘人走回過去RPC的作法,有失SOA的基本精神。實際上,令人最憂心的,是WS-* 這個標準越來越複雜,幾乎已經到只有全職專家才讀得懂的地步,最後可能會生出壓垮駱駝背的稻草。不管如何,這派有所有大軟體公司及W3C的支持,在企業CIO間,不管未來後果,可能比較容易被接受。

鼓吹網際網路精神的這派,主張把介面上的運作(operation)限制到HTTP這種通訊協定所允許的四、五種方式,利用URI的層次性來豐富內涵,並以資源(resource)這種觀念為設計中心。這派人的理論依據是Roy Fielding的博士論文中叫REST (REepresentational State Transfer)的架構風格。由於HTTP是不記狀態(stateless) 的,而網際網路發展到今可證明它延伸性是很高的,所以這派的簡化與延伸性思考,受到很多人的歡迎。這種作法的缺點是它跟主流的物件導向語言不是很相符,所以無法用工具直接轉譯,造成門檻較高。另一個缺點是它嚴格的不記狀態要求,使得驗證(authentication)及效能(performance)上需要小心。REST這種架構風格,加上比XML更簡潔的JSon資料語言,是目前網際網路上很流行的服務介面方式oogle和Amazon都以此為主要對外開放的API。3

另一個更加激進的派系,把過去訊息導向(Message-oriented)的方式提出來,主張把所有服務都視為信箱,而呼叫服務就視為把信件塞入信箱。以這種叫MEST(MESsage Transfer)方法來看,運作本身幾乎被簡化到無法再簡化的方式,而真正的訊息,不打開信是無法知道的。這樣的好處是:要求服務的與提供服務的幾乎沒有連結性,系統可以擁有最大的彈性。這類思考的缺點是:就像把Java程式裡所有的變數的型態都宣告成Object一樣,你幾乎無法分析服務之間的性質。

SOA解決系統複雜度的新利器

現有SOA絕大多數都是利用Web Services加上HTTP來達成,這免除了廠商之間的政治鬥爭,也免除了很多在通訊協定(protocols)上的困擾4。這樣的處理,讓大家開始尊重W3C或是OASIS這樣的機構,也大致尊重通過的國際標準,而不是像以往那樣各行其事。標準化對系統的生命是很重要的:有些軟體大廠利用這波SOA熱潮來促銷一些他們的解決方案與產品,但是這類產品,都可能綁住你未來發展的自由度,也可能有做過頭(over-done)的可能性,因此未必都是必要的。也有些塑造輿論的評論家聲稱:沒有企業流程管理機制(Business Process Management, BPM)在服務層上指揮,或是企業服務匯流(Enterprise Service Bus, ESB)當作各服務間協調的機制,SOA就做得不全。我想這些有爭議性的論點,即使現階段不採用,也不會減損了SOA突顯服務層的好處。所以企業資訊主管在將自己現有或未來應用系統推向SOA之路時,應當要謹慎從事。

SOA是我們跟複雜度(complexity)奮戰的新武器;這武器是將舊的思考,以新的組合方式,用來對抗新的問題。隨著系統複雜度升高,整合對象與種類越變越多,原本沒預料到的應用組合也會隨著來。不管下一個炒作詞是什麼,也不管下一個時尚的解法是什麼,我們基本的態度是要把解法的本質和根據的原理整理出來,那麼隨之採取的措施也不會相差太遠。