幾種企業應用整合方式的比較
前言
我們做過的大部分系統其實並不是自己從頭開始設計和實現的,很多時候是基於現有的基礎再做擴充套件或者和現有的系統整合。尤其是很多企業應用的系統,因為我們定義的很多子系統是為了解決某個特定的問題或者問題域,在後續隨著業務的發展和變化對於系統也會有更多的整合要求。於是,整合主要有哪幾種方式?他們各有什麼特點呢?這些問題就一一的浮現出來。這裡主要針對一些原來個人專案中接觸過的問題,結合一些前人的經驗做一個總結。
企業整合要點
通常來說,我們需要將多個應用系統整合起來是的他們之間能夠相互互動。出於系統演化和需求變更的影響,由於系統的差異導致我們整合的時候面臨的困難也比較繁雜。很多時候我們最開始在設計某些系統的時候根本就沒有考慮到整合的需要。因此在整合的時候主要會考慮一下幾個要點:
- 應用耦合度:這一點也和軟體工程中的基本設計思想是契合的。即我們要求系統之間的依賴達到最小化,這樣當一個系統發生變化的時候也會對另外一個系統產生儘可能小的影響。也就是我們所說的鬆耦合。
- 侵入性:當進行整合的時候,希望整合的系統和整合功能的程式碼都儘可能的變動小。
- 技術選擇:不同的整合方案需要不同的軟硬體,這些牽涉到開發和學習的成本。
- 資料格式:既然系統要整合,從本質上來說就相當於兩個系統的通訊。那麼相互通訊的系統就要確定交換的資料資訊格式來保證通訊的正常進行。我們接觸過的SOAP, REST web service, CORBA等都有特定的訊息定義標準。
- 資料時間線:整合還有一個需要考慮的就是當一個系統將需要傳遞資料傳送給另外一個系統的時候,他們傳送時間要儘可能少。這樣可以提升系統整體執行的效率,減少延遲。
- 資料或功能共享:有的應用整合還考慮到功能的整合共享。這種功能的共享帶來的好處是使得一個系統提供的功能在另外一個系統看來就好像是呼叫本地的功能一樣。一些典型的應用整合比如說RPC(遠端方法呼叫)就符合這種特徵。
- 遠端通訊:通常我們系統呼叫是採用同步的方式。可以在一些遠端通訊的情況下,採用非同步的方式也有它的優點,比如說帶來系統效率的提升。同時也使得系統設計的複雜度變大。
- 可靠性:我們不僅僅是設計系統整合方案,就是在一些簡單系統應用裡面也會考慮到,如果某個部分出錯了或者失效了該怎麼辦?有什麼辦法可以提高可靠性?
OK,有了前面這些要點,我們再結合目前幾種主要的整合方式來一一討論吧。
檔案傳輸(共享)
檔案共享傳輸的方式是一種我們能想到的很簡單直觀的辦法。它的典型互動場景如下:
在這種場景下,我們一個應用產生包含需要提供資訊的檔案,然後再由另外一個應用來通過訪問檔案獲取資訊。在這裡,整合部分所做的事情主要是將檔案根據應用的不同需要做格式的轉換。考慮這種整合方式,我們有幾個重要的問題需要考慮:
- 檔案的格式:考慮到不同應用系統傳遞訊息的具體樣式不一致,A應用產生的檔案如果能夠給B應用直接使用是最好的了。尤其是如果如果有B應用的原生支援,對於整合來說將大大提高效率。因此,我們一些常見的方法是傳遞XML或者JSON格式的文字。 當然,在一些UNIX系統裡面也有通過純TXT文字傳遞資訊的。
- 另外一個比較重要的問題就是什麼時候產生檔案,什麼時候處理檔案。因為我們一般都需要一定的時間來產生檔案,我們不太希望檔案產生的太頻繁。而且,在一個應用產生檔案的時候怎麼保證另外一個應用這個時候不去修改它呢?如果檔案產生完了怎麼通知另外一個應用呢?還有就是,我怎麼知道另外一個應用已經處理過我處理的檔案了?我們產生的檔案會不會有重名的衝突?檔案被處理完之後該怎麼辦?刪除它還是重複再應用?這些問題是在訊息傳輸比較頻繁時很容易發生的。這些問題的發生會導致兩個應用系統之間資訊的不同步或者資訊的錯誤,這也是採用純檔案傳輸的弊端。
- 當然,在一些應用場景之下,檔案傳輸還是有其優點的。在一些資訊交換不是很頻繁,而且對於資訊的及時性要求不太高的情況下,這種方式還是值得考慮的。我們可以採用一些timer job的方式來產生和消費檔案。只要保證兩者不產生衝突和他們正確的執行順序。整合的效果還是可以達到的。另外,採用檔案傳輸還有一個優點就是對於整合的系統來說它比較完美的遮蔽了整合的細節。每個系統只要關注符合標準格式的檔案內容,具體實現和資料交換他們都不需要關心。
共享資料庫
還有一種整合方式也比較常見,就是共享資料庫。在很多應用開發的場景下,我們的資料庫是相對獨立提供服務的一部分。所以對於其他系統的對接也就比較容易,這種整合的方式如下圖:
和前面檔案共享傳輸的方案比起來,這種方案有一個相對的優勢,就是可以保證資料的一致性。在原來的方案中,如果檔案要傳輸給多個應用的話,我們是沒辦法保證所有應用的資料是同步而且一致的。有可能有的快有的慢。而在這裡,所有的資料都是統一儲存在公共的資料庫裡,也就不存在這樣的問題了。對於任何一個系統產生的資料或者變化,另外一個系統也就馬上可以看到。
當然,這種方案也有它不足的地方。首先一個問題就是對於多個應用來說,這個共享資料庫需要能夠適應他們所有的場景。不同的應用考量的點是不一樣的,要能適應所有的需求對於資料庫這一部分就顯得尤其的困難。還有一個就是效能方面的問題,不同的應用可能會同時訪問相同的資料導致資料訪問衝突,因此也會帶來如死鎖等問題。
所以說,這種方案出現問題的根源在於用一種統一的資料模型來解決各種不同的應用需求是並不現實的。
RPC(遠端過程呼叫)
遠端過程呼叫的方法在早些年的時候也比較常見。典型的如Java的RMI。典型的應用場景如下:
以典型的java RMI為例,當我們需要訪問遠端方法的時候,需要定義訪問的介面,然後通過相關工具生成skeleton和stub。然後一端通過stub給另外一端傳送訊息。在應用A本地的程式碼中訪問stub看起來還是和呼叫本地方法一樣,這些細節都由stub給遮蔽了。其他的技術如COM, CORBA, .net Remoting都採用了RPC的思路。
RPC的這種思路能夠很好的整合應用開發。當然,由於這種機制也會帶來一定的問題,比如說java RMI或者.net remoting。他們都侷限於一個平臺,好比說我應用A是用java做的,那麼如果要和另外一個系統通過RMI整合的話,那個系統也必須是java做的。另外,他們其實還是一種緊耦合。我們RPC呼叫是用的一種類似於系統api的同步呼叫,當一端發出呼叫請求的時候會在那裡等待返回的結果。如果另外一個系統出現故障也會對呼叫方產生很大影響。而且我們用RPC呼叫的時候預設期望訊息是按照發送的順序給接收方的。但是由於各種環境的影響會使得接收的結果亂序,這樣也可能會導致系統執行出現問題。所以從可靠性來說還是存在著一定的不足。
訊息佇列
看來前面幾種整合的方式,我們再來看看訊息佇列的方式。訊息佇列的整合方式如下圖:
所有應用之間要通訊的訊息都通過訊息佇列來傳輸,由訊息佇列來保證資料傳輸的非同步性、穩定性等。總的來說,這看起來有點像網路連線結構。所有資料通過一條可靠的鏈路來進行通訊。
那麼,這種整合方式有哪些特徵呢?
- 更好的應用解耦:像以往採用檔案傳輸或者共享資料庫的方式需要知道檔案或者資料庫在哪裡。對於RPC的方式來說甚至要知道對方的IP地址才能進行方法呼叫。這樣的依賴太強烈。而且還對開發執行平臺也有依賴。而現在這種方式則是隻要雙方規定好通訊的訊息格式,各自都只要發訊息給訊息佇列就可以了。這就好比是兩個人寫信,一個人只要把要寫的內容整理好再交給郵局,剩下的事情他就不用操心,全讓郵局給他辦了。這樣,不管對方是什麼語言開發的系統,只要他們採用統一的訊息格式,java開發的系統也就能夠和C++, .net等平臺的系統通訊了。
- 訊息的可靠性:我們具體傳送訊息的任務相當於交給了訊息佇列。所有提交的訊息有訊息佇列裡的message router來投遞。這有點像網路概念裡的路由器一樣,根據一個傳送方指定的地址並轉發到另外一個地方。同時,訊息佇列也根據不同的需要將訊息進行持久化,這樣保證訊息在投遞的過程中不會被丟失。
- 系統可靠性:如果對訊息佇列和RPC的方式做一個對比,這就好比是生活中打電話和發簡訊的區別。在打電話的時候,我們是必須期望接電話的對方在電話旁邊能夠接收響應。而如果接收人不在或者忙的話,打電話的這一方就只能在這裡乾等。這就是系統不夠健壯的地方,一旦另外一方系統出故障,系統就沒法正常運作。而且要保證能夠正常通訊,需要系統雙方都同時就位。而發簡訊的這種訊息方式則不然,訊息可以準確的送達到對方,如果對方暫時忙訊息也會儲存在那裡。等有空的時候會進行回覆。至少保證了有效資訊的傳遞。這種特性也就是保證了系統的非同步執行,從某種角度來說也提升了系統性能。
綜合上面的這些討論,訊息佇列算是一種兼顧了效能、可靠性和鬆耦合的一種理想整合方式。目前實現訊息佇列的產品有很多,比如微軟的MSMQ, 開源產品ActiveMQ, RabbitMQ, ZeroMQ等。後續的文章還會對訊息佇列的應用和內部機制做深入的分析。
總結
應用系統整合的方式有很多,最常見的幾種有檔案傳輸,資料庫共享,遠端方法呼叫以及訊息佇列。他們在解決某些特定領域的問題時有自己的特長。綜合來說,訊息佇列算是一種比較理想的解決方案。不同事物或者不同領域之間也有很多的相似性,在研究訊息佇列的時候會發現他們和網路的體系結構思想非常相似。