服務的實例管理問題,一般有SINGLETON和SINGLECALL等方式。推薦采用SINGLECALL方式,如果服務具有狀態的話會大大增加服務的開發難度,一是需要考慮線程同步問題,二是需要考慮生命周期。其實,我一直覺得有狀態的服務配合ORM數據訪問層的使用是很好的,但做起來可能會遇到很多問題。
在存儲過程中做事務還是很簡單的,SOA如果要做分布式事務的話,實現不是打大問題,但性能是很大的問題,很容易引起數據庫對象的死鎖。大多數情況下我們對分布式事務的替代方式是采用隊列,放到隊列中的東西就認為是一定可以成功的,對于不使用隊列的情況,如果調用失敗了則記錄日志,不會進行回滾。除非涉及到錢的地方才做分布式事務。
版本問題也是需要考慮的。傳統的實現方式是,如果新增接口的話以前的程序是沒有影響的,如果萬不得已需要修改接口的話就大吼一聲,我這個接口要改了,然后給大家發一份,請調用者按照我的要求修改一下,連同我的服務一起重新發布。對于WCF的話,有MEX元數據交換,這樣就不用手動引用新的契約,只需要從HTTP地址上更新新的服務即可。但有一個不得不考慮的問題就是萬一在調用其它服務的時候發生錯誤了,我們怎么知道是哪個服務的版本出現問題了呢。我們是這樣做的,調用服務的代理有一層封裝,如果網絡調用發生錯誤的話,會記錄詳細的錯誤信息,哪個服務(服務的版本)、哪個方法在哪個端點上的調用、傳入的參數是什么,返回的是什么。這樣,在部署的過程中發生錯誤或是版本問題,我們就很容易知道錯誤的原因了。那么怎么知道服務的版本呢?沒一個服務都約定有一個GetVersion方法,這個方法兩個作用,一是給管理工具測試這個服務是不是還有效,二是給配置服務獲取服務的版本號。
如果引入SOA的話,不可避免的是大大增加了整個系統的部署復雜性。想一下,在LIVE上,我們可能有20個WEB服務器,10個APP服務器(我們以前是2:1這樣進行配置的,服務按照類型和資源不同放在不同的APP服務器,WEB服務器CPU特別強,APP服務器是廉價服務器,有足夠大的內存,對于WEB程序來說確實沒什么大的CPU計算,服務也就是緩存比較厲害)。10個APP服務器上放100個服務,就產生了100個端點地址。開發人員其實不用考慮服務在LIVE上怎么部署的,需要架構師在部署的時候協調部署團隊一起完成部署工作,架構師知道哪個服務部署在哪個服務器最合理,以哪種信道進行部署最合適。部署團隊需要對各個服務器的結構很清楚,也要學會使用健康監控工具(我前面提到的監控服務運行狀態的工具和異常管理工具來發現部署上的問題),這就對部署團隊的要求更高了。實在不行的話可以要求開發人員參與,開發人員應該沒權限直接進行服務的部署,但是有權使用兩個工具的,一來用于排查問題,二來也會有很大的成就感。
服務監控工具以一個拓撲圖形式展現整個網絡上WEB服務器、APP服務器的IP地址、CPU內存使用,以及服務的引用情況和每一個服務對CPU和內存的占用,以及服務的健康情況。監控人員24小時值班負責監控,出問題的時候及時重新啟動相關服務。異常管理工具每天收集各個系統的異常,開發人員每天上班和下班的時候查看一次這個工具,知道自己負責的模塊產生了哪個異常(異常有幾種,一種是程序有BUG,一種是外部有人在攻擊造成的,還有一種是前面說的服務的版本和運行問題產生的異常)。當然,架構師也應該時刻關注這2個工具,知道整個系統的健康情況。
從網絡上來說,APP服務器應該跨2個網段,DB服務器應該外部不能直接訪問,所有數據庫操作都是通過APP服務器提供的服務訪問DB的,網站不具有任何連接字符串不能直接訪問DB服務器(不在同一網段)。WEB服務器和APP服務器之間應該走TCP,如果是跨國的話應該有VPN鏈路。
從軟件架構上來說,我們以前使用的是.NET Remoting對內,Web服務對外的方式,中間層以Windows服務作為載體。對于.NET 3.5時代,可以采用WCF+Windows服務承載的方式。WCF支持元數據交換是一個優點,另一個優點是方便TCP/HTTP各種綁定的切換,當然也可以同時提供多份綁定。如果是細粒度服務的話,可以使用ADO.NET DATA SERVICE+ADO.NET EF的方式直接進行提供。表現層可以直接使用ADO.NET DATA SERVICE也可以使用自定義的JSON/XML數據,不屬于SOA的范疇就不擴展了。
總結一下:
對于ETOWN的應用,SOA架構是絕對適合的。
文章來源于領測軟件測試網 http://www.kjueaiud.com/