|
注:本文來(lái)源于我給公司內(nèi)部發(fā)的郵件中,所以背景都是基于我們現(xiàn)在的應(yīng)用,而且思路也很混亂,請(qǐng)大家見(jiàn)諒。
自05年開(kāi)始接觸到分布式架構(gòu),06年在原先的基礎(chǔ)上從頭開(kāi)始設(shè)計(jì)了一套分布式架構(gòu),當(dāng)時(shí)SOA這個(gè)概念也沒(méi)這么火。整個(gè)大平臺(tái)的開(kāi)發(fā)、性能和可擴(kuò)展性都得到了考驗(yàn),覺(jué)得有一些東西想和大家一起分享。
我不知道我所說(shuō)的這些算不算真正的SOA,我也沒(méi)讀過(guò)什么SOA的書(shū)籍,我覺(jué)得SOA這個(gè)概念非常抽象,任何概念的產(chǎn)生都是由原因的。因此,我也不會(huì)說(shuō)一些抽象的原則,只是想說(shuō)一些在過(guò)去幾年實(shí)施“SOA”過(guò)程中的一些心得和一些細(xì)節(jié),希望對(duì)大家有用。
不說(shuō)什么是SOA,先來(lái)說(shuō)說(shuō)我們現(xiàn)有架構(gòu)遇到的一些問(wèn)題:
- 同樣一個(gè)邏輯,A系統(tǒng)(ASP)使用COM實(shí)現(xiàn)一份(我們現(xiàn)在的Java庫(kù)),B系統(tǒng)(.NET)在開(kāi)發(fā)的時(shí)候覺(jué)得調(diào)用Java也是很麻煩的,索性自己實(shí)現(xiàn)一份邏輯,可能是存儲(chǔ)過(guò)程,也可能是在代碼中硬編碼SQL,C系統(tǒng)(由系統(tǒng)部門(mén)開(kāi)發(fā)的.NET程序)也用到了相同的邏輯,由于和產(chǎn)品部門(mén)缺乏必要的溝通,也實(shí)現(xiàn)了一份邏輯。最后,如果這個(gè)相同的邏輯需要修改,則需要修改A、B、C三個(gè)系統(tǒng),一份邏輯在三個(gè)地方實(shí)施有幾個(gè)缺點(diǎn),一來(lái)是因?yàn)槿绻枰薷囊娜齻€(gè)地方,二來(lái)是增加了工作量,三來(lái)是占用了不必要的資源(因?yàn)榇蠹铱赡芏紝?shí)現(xiàn)了自己的緩存)。
- 所有網(wǎng)站全部部署在一個(gè)WEB服務(wù)器上,直接實(shí)現(xiàn)負(fù)載均衡。這樣的方案有幾個(gè)缺點(diǎn),一是幾乎沒(méi)一個(gè)網(wǎng)站程序都有自己的緩存,每臺(tái)服務(wù)器的緩存是冗余的,而且甚至每個(gè)網(wǎng)站中的緩存都有重復(fù),二是如果一個(gè)網(wǎng)站有問(wèn)題會(huì)影響到其它網(wǎng)站(比如進(jìn)程回收,應(yīng)用程序池不能100%解決這個(gè)問(wèn)題,而且我們現(xiàn)在并沒(méi)有注重應(yīng)用程序池的劃分,又比如某些應(yīng)用是長(zhǎng)請(qǐng)求、過(guò)長(zhǎng)時(shí)間占用線程),三是不能有效利用服務(wù)器資源,這是因?yàn)椴皇敲恳粋€(gè)網(wǎng)站都具有相同的訪問(wèn)量,不是每一個(gè)網(wǎng)站都需要相同的資源(有些需要特別多IO、有些需要特別多CPU、有些甚至是內(nèi)存)。
雖然說(shuō)我們現(xiàn)在是使用了三層架構(gòu),但并沒(méi)有什么重用,而且所有的層還是部署在相同的服務(wù)器上的。為了解決前面的2大問(wèn)題,我們首先想到了:
- 是不是有什么方法可以讓相同的邏輯被其它系統(tǒng)重用?
- 是不是考慮把邏輯以服務(wù)的形式對(duì)外部(其他模塊)公開(kāi)?
由此引入面向服務(wù)架構(gòu)的概念,我們通過(guò)這些公開(kāi)的服務(wù)進(jìn)行邏輯的重用,提高系統(tǒng)性能也降低了模塊之間的耦合性。架構(gòu)圖見(jiàn)我以前寫(xiě)的文章http://www.cnblogs.com/lovecherry/archive/2008/06/18/1224496.html
如果確實(shí)采用這種架構(gòu),我們的開(kāi)發(fā)方式會(huì)有什么改變呢?
- 在一般情況下,我們一般認(rèn)為A系統(tǒng)對(duì)應(yīng)A數(shù)據(jù)庫(kù),B系統(tǒng)對(duì)應(yīng)B數(shù)據(jù)庫(kù),每一個(gè)系統(tǒng)都有自己的數(shù)據(jù)庫(kù)。傳統(tǒng)的方式是A系統(tǒng)和B系統(tǒng)在數(shù)據(jù)庫(kù)端直接使用JOIN進(jìn)行交叉耦合。如果實(shí)施SOA的話(huà),最佳實(shí)踐應(yīng)該是對(duì)于大多數(shù)系統(tǒng)來(lái)說(shuō),禁止A系統(tǒng)直接訪問(wèn)B系統(tǒng)的數(shù)據(jù)庫(kù),反之亦然。我要你的數(shù)據(jù),就必須調(diào)用你公開(kāi)的服務(wù)。而且這個(gè)服務(wù)或者說(shuō)接口或者說(shuō)契約,盡量是粗粒度的。比如一個(gè)邏輯包括X和Y和Z三個(gè)過(guò)程,如果獨(dú)立提供三個(gè)方法的話(huà),每一次方法調(diào)用都是網(wǎng)絡(luò)調(diào)用的過(guò)程,性能比較低,而且更重要的原因,這個(gè)模塊提供了這么細(xì)粒度的三個(gè)方法,如果這三個(gè)構(gòu)成了一定邏輯的話(huà),很有可能這個(gè)邏輯就在調(diào)用方和提供方兩個(gè)模塊都實(shí)現(xiàn)了相同的邏輯。雖然說(shuō)確實(shí)是提供了服務(wù),但是沒(méi)有達(dá)到封裝邏輯這個(gè)重要的目的,而且也產(chǎn)生了性能的下降,這種服務(wù)就顯得很不值得。
- 一個(gè)大系統(tǒng)有許多模塊或者說(shuō)子系統(tǒng),每一個(gè)都有自己的復(fù)雜邏輯和存儲(chǔ)結(jié)構(gòu)。開(kāi)發(fā)人員可能只熟悉自己的那一部分,如果我的系統(tǒng)確實(shí)要用到其它系統(tǒng)的數(shù)據(jù),按道理是應(yīng)該想到調(diào)用它提供的程序集。很多時(shí)候我們并沒(méi)有這么做,是因?yàn)槲覀儾⒉恢缹?duì)方有沒(méi)有提供我需要的功能,即使知道提供了也不知道怎么去使用,如果要去用的話(huà)可能熟悉對(duì)方系統(tǒng)的時(shí)間會(huì)比直接在數(shù)據(jù)庫(kù)中進(jìn)行JOIN需要的時(shí)間還要長(zhǎng)。這是一種惡性循環(huán),因?yàn)檫@樣又導(dǎo)致了一個(gè)邏輯在多處出現(xiàn),一份數(shù)據(jù)在多處取得、保存和緩存。有了SOA,我們應(yīng)該能在SHAREPOINT或WIKI上看到一份清單,在哪個(gè)HTTP或TCP端點(diǎn)上具有什么服務(wù),服務(wù)中有哪些方法,這些方法是干什么的,返回什么,傳入什么,使用的注意事項(xiàng),如果我開(kāi)發(fā)的系統(tǒng)需要用到外部的數(shù)據(jù),我第一時(shí)間想到的不應(yīng)該是去看數(shù)據(jù)庫(kù)中我需要的數(shù)據(jù)在哪里,而是應(yīng)該是去看看是否對(duì)方系統(tǒng)提供了這樣的服務(wù),如果沒(méi)有提供的話(huà)則和服務(wù)的提供者進(jìn)行一些溝通。你可能會(huì)問(wèn),我作為系統(tǒng)的開(kāi)發(fā)者,我也不知道要對(duì)外提供哪些服務(wù),我也不知道別人需要用到什么,確實(shí)是,但是至少我們現(xiàn)在可以做的是把內(nèi)部使用到的一些邏輯以服務(wù)形式對(duì)外公開(kāi),一般來(lái)說(shuō)自己系統(tǒng)的這些函數(shù)如果能滿(mǎn)足自己要求的話(huà)從功能上來(lái)說(shuō)可以滿(mǎn)足別人要求,只不過(guò)別人可能需要的并不是這么多罷了。
- 我們現(xiàn)在做TECH SPEC的時(shí)候可能關(guān)注內(nèi)部的實(shí)現(xiàn),如果是SOA的話(huà),我們就需要關(guān)注現(xiàn)在在做的這個(gè)系統(tǒng)會(huì)用到別人的哪些接口,別人可能會(huì)用到我什么接口,我需要公開(kāi)出來(lái)。可能還會(huì)考慮,我用了ABC三個(gè)系統(tǒng)的接口,是否需要把這個(gè)邏輯以粗粒度服務(wù)公開(kāi)出來(lái)。每一個(gè)公開(kāi)接口的參數(shù)、返回都需要仔細(xì)考慮,把這些都列入到架構(gòu)設(shè)計(jì)中,和架構(gòu)師一起完成服務(wù)的定義。開(kāi)發(fā)人員可能只對(duì)自己系統(tǒng)的接口和邏輯比較熟悉,架構(gòu)師的作用是給開(kāi)發(fā)人員建議,哪些接口你可能需要,哪些接口你可能需要對(duì)外提供,是否需要做緩存。
- 我們現(xiàn)在的部署是非常簡(jiǎn)單的,如果實(shí)施了SOA,很有可能一個(gè)系統(tǒng)需要調(diào)用十幾個(gè)外部子系統(tǒng)的接口,每一個(gè)接口都需要制定地址、調(diào)用策略以及契約。地址和調(diào)用策略需要是可配置的,一般定義在配置文件中或者數(shù)據(jù)庫(kù)中,這樣一個(gè)系統(tǒng)的部署可能非常復(fù)雜,打個(gè)比方就像芯片的引腳一樣,有很多,一個(gè)引腳沒(méi)有接到合適的地方,系統(tǒng)就不能工作。雖然部署負(fù)責(zé)了,但是系統(tǒng)之間的耦合非常小的,大家只是依賴(lài)于某個(gè)網(wǎng)絡(luò)環(huán)境中的地址,依賴(lài)于某個(gè)契約。這樣的話(huà),系統(tǒng)的伸縮性就很強(qiáng),有些服務(wù)需要很高的資源,就給獨(dú)立的服務(wù)器,有些服務(wù)占用資源很小,可以合并在一起。當(dāng)然,也可以根據(jù)服務(wù)的性質(zhì),比如特別需要IO、特別需要CPU來(lái)分配到合適的服務(wù)器上。服務(wù)器并不一定是一樣的,有的服務(wù)器內(nèi)存特別大,有的服務(wù)器CPU特別好。
- 還會(huì)遇到一個(gè)問(wèn)題,就是開(kāi)發(fā)人員不太愿意調(diào)用其它的接口。一是對(duì)別人的東西往往默認(rèn)會(huì)覺(jué)得是實(shí)現(xiàn)糟糕的,性能很差的,二是覺(jué)得不放心,會(huì)不會(huì)到時(shí)候你沒(méi)給我正確的數(shù)據(jù),影響我的開(kāi)發(fā),產(chǎn)生相互推卸責(zé)任的問(wèn)題。其實(shí),這種想法不對(duì),一個(gè)人不可能開(kāi)發(fā)系統(tǒng)的全部,作為使用者來(lái)說(shuō)要使用別人的接口信任別人的接口,作為接口提供者來(lái)說(shuō)需要積極對(duì)自己的接口負(fù)責(zé),進(jìn)行完善的單元測(cè)試,如果調(diào)用者有特別的需求在討論后進(jìn)行改進(jìn)。這也就是說(shuō)引入SOA的話(huà),我們需要更多的溝通。
說(shuō)的有點(diǎn)亂,接下來(lái)想說(shuō)說(shuō)我在實(shí)施過(guò)程中遇到的一些細(xì)節(jié)問(wèn)題,很多時(shí)候SOA實(shí)施的失敗都是因?yàn)橐恍┘?xì)節(jié)。 - SOA的接口設(shè)計(jì)必須基于業(yè)務(wù)的。架構(gòu)師應(yīng)該是一個(gè)總導(dǎo)演,對(duì)所有系統(tǒng)的業(yè)務(wù)都有一個(gè)認(rèn)識(shí),理解業(yè)務(wù)之間的關(guān)系,和開(kāi)發(fā)人員一起定義合理的接口。這包括,接口是否代表了業(yè)務(wù)、是否是合適的粒度、是否會(huì)有性能問(wèn)題,別小看接口設(shè)計(jì),一旦確定以后很難修改,接口的好壞決定成敗,我列為第一要素。
- 在實(shí)施中,管理很關(guān)鍵,有許多要點(diǎn)是需要有強(qiáng)制的。比如除非特殊需要不能直接引用其它數(shù)據(jù)庫(kù),即使是本系統(tǒng)也應(yīng)該引用本系統(tǒng)的服務(wù),也就是說(shuō)網(wǎng)站項(xiàng)目里面沒(méi)有連接字符串、沒(méi)有數(shù)據(jù)訪問(wèn)邏輯,只有端點(diǎn)的配置。還比如是A系統(tǒng)的開(kāi)發(fā)人員有這個(gè)責(zé)任為A系統(tǒng)對(duì)外的所有接口進(jìn)行后續(xù)的維護(hù)和功能擴(kuò)展,不是說(shuō)A系統(tǒng)結(jié)束了,我的數(shù)據(jù)我也不管,不行,別人如果需要的數(shù)據(jù)確實(shí)是我的數(shù)據(jù)的話(huà),我就要管。
- 從性能角度考慮,一般內(nèi)網(wǎng)中的服務(wù)通訊采用TCP(二進(jìn)制序列化),公網(wǎng)的走HTTP。還有一種方式是IPC方式,進(jìn)程間通訊,我們以前也用的挺多的,雖然說(shuō)緩存應(yīng)該在一個(gè)地方建立。但很多時(shí)候,某個(gè)方法的調(diào)用是每次訪問(wèn)頁(yè)面都需要進(jìn)行一次或多次的,如果再進(jìn)行網(wǎng)絡(luò)調(diào)用的話(huà)性能很成問(wèn)題,比如論壇上的臟話(huà)過(guò)濾,如果某個(gè)臟話(huà)服務(wù)提供了臟話(huà)過(guò)濾的接口,如果這個(gè)這個(gè)接口需要TCP調(diào)用的話(huà)性能不高,這個(gè)時(shí)候我們會(huì)考慮把這個(gè)服務(wù)部署在WEB服務(wù)器上,而不是APP服務(wù)器上,IPC方式進(jìn)行進(jìn)程間通訊。
- 到最后我們會(huì)發(fā)現(xiàn)我們有20個(gè)子系統(tǒng),也就至少有20個(gè)服務(wù)(一般是以Windows服務(wù)部署在APP服務(wù)器上)。而且如果服務(wù)部署多份做負(fù)載均衡的話(huà),可能就有上百個(gè)網(wǎng)絡(luò)地址。一個(gè)網(wǎng)站如果引用了5個(gè)服務(wù),就需要一個(gè)一個(gè)IP地址(或者說(shuō)端點(diǎn))進(jìn)行配置,如果將來(lái)服務(wù)遷移,那么這些網(wǎng)站的配置文件修改是一個(gè)大問(wèn)題。雖然說(shuō)我們會(huì)有一個(gè)拓?fù)鋱D來(lái)描述網(wǎng)站之間服務(wù)的依賴(lài)情況,但是配置文件的修改工作量不小而且容易出錯(cuò)。推薦的做法是有一個(gè)數(shù)據(jù)庫(kù)來(lái)存放所有服務(wù)的端點(diǎn)定義、描述,使用一個(gè)單獨(dú)的服務(wù)來(lái)提供所有服務(wù)的端點(diǎn)信息,在網(wǎng)站中只需要配置這個(gè)服務(wù)的端點(diǎn)信息,然后引用各種服務(wù)的契約就可以了。考慮到效率關(guān)系,在每一個(gè)WEB服務(wù)器上都安裝有這個(gè)配置服務(wù),以IPC方式提供所有網(wǎng)站進(jìn)行調(diào)用,當(dāng)然,其中的端點(diǎn)信息都會(huì)做緩存。
- 前面說(shuō)的是網(wǎng)站引用服務(wù)的端點(diǎn)信息配置問(wèn)題,還有一個(gè)問(wèn)題就是服務(wù)的健康監(jiān)視問(wèn)題,服務(wù)是以Windows服務(wù)形式運(yùn)行的,我們需要檢測(cè)Windows服務(wù)的狀態(tài),占用的CPU和內(nèi)存信息。我們?cè)诿恳粋€(gè)APP服務(wù)器上又裝有一個(gè)AGENT服務(wù),專(zhuān)門(mén)用于監(jiān)視這些服務(wù)進(jìn)程的情況,一旦發(fā)現(xiàn)問(wèn)題會(huì)第一時(shí)間通知網(wǎng)絡(luò)部門(mén)甚至是開(kāi)發(fā)人員,當(dāng)然服務(wù)無(wú)響應(yīng)的情況比較少,一般常見(jiàn)的情況是服務(wù)沒(méi)有正確部署(缺少DLL不能啟動(dòng)),或者是占用了過(guò)多的內(nèi)存。這個(gè)AGENT的另外一個(gè)作用就是收集服務(wù)器上的錯(cuò)誤日志,并且負(fù)責(zé)更新和重啟服務(wù)。也就是說(shuō)所有服務(wù)的更新是自動(dòng)化的更新,我們發(fā)布的時(shí)候發(fā)布到指定的RELEASE服務(wù)器,由專(zhuān)門(mén)的管理工具進(jìn)行服務(wù)的自動(dòng)更新,服務(wù)如果做負(fù)載均衡的話(huà)手動(dòng)更新很麻煩。而且很多情況下相同的服務(wù)需要在多個(gè)服務(wù)器部署,比如IPC服務(wù) 。
- 服務(wù)的實(shí)例管理問(wèn)題,一般有SINGLETON和SINGLECALL等方式。推薦采用SINGLECALL方式,如果服務(wù)具有狀態(tài)的話(huà)會(huì)大大增加服務(wù)的開(kāi)發(fā)難度,一是需要考慮線程同步問(wèn)題,二是需要考慮生命周期。其實(shí),我一直覺(jué)得有狀態(tài)的服務(wù)配合ORM數(shù)據(jù)訪問(wèn)層的使用是很好的,但做起來(lái)可能會(huì)遇到很多問(wèn)題。
- 在存儲(chǔ)過(guò)程中做事務(wù)還是很簡(jiǎn)單的,SOA如果要做分布式事務(wù)的話(huà),實(shí)現(xiàn)不是打大問(wèn)題,但性能是很大的問(wèn)題,很容易引起數(shù)據(jù)庫(kù)對(duì)象的死鎖。大多數(shù)情況下我們對(duì)分布式事務(wù)的替代方式是采用隊(duì)列,放到隊(duì)列中的東西就認(rèn)為是一定可以成功的,對(duì)于不使用隊(duì)列的情況,如果調(diào)用失敗了則記錄日志,不會(huì)進(jìn)行回滾。除非涉及到錢(qián)的地方才做分布式事務(wù)。
- 版本問(wèn)題也是需要考慮的。傳統(tǒng)的實(shí)現(xiàn)方式是,如果新增接口的話(huà)以前的程序是沒(méi)有影響的,如果萬(wàn)不得已需要修改接口的話(huà)就大吼一聲,我這個(gè)接口要改了,然后給大家發(fā)一份,請(qǐng)調(diào)用者按照我的要求修改一下,連同我的服務(wù)一起重新發(fā)布。對(duì)于WCF的話(huà),有MEX元數(shù)據(jù)交換,這樣就不用手動(dòng)引用新的契約,只需要從HTTP地址上更新新的服務(wù)即可。但有一個(gè)不得不考慮的問(wèn)題就是萬(wàn)一在調(diào)用其它服務(wù)的時(shí)候發(fā)生錯(cuò)誤了,我們?cè)趺粗朗悄膫€(gè)服務(wù)的版本出現(xiàn)問(wèn)題了呢。我們是這樣做的,調(diào)用服務(wù)的代理有一層封裝,如果網(wǎng)絡(luò)調(diào)用發(fā)生錯(cuò)誤的話(huà),會(huì)記錄詳細(xì)的錯(cuò)誤信息,哪個(gè)服務(wù)(服務(wù)的版本)、哪個(gè)方法在哪個(gè)端點(diǎn)上的調(diào)用、傳入的參數(shù)是什么,返回的是什么。這樣,在部署的過(guò)程中發(fā)生錯(cuò)誤或是版本問(wèn)題,我們就很容易知道錯(cuò)誤的原因了。那么怎么知道服務(wù)的版本呢?沒(méi)一個(gè)服務(wù)都約定有一個(gè)GetVersion方法,這個(gè)方法兩個(gè)作用,一是給管理工具測(cè)試這個(gè)服務(wù)是不是還有效,二是給配置服務(wù)獲取服務(wù)的版本號(hào)。
- 如果引入SOA的話(huà),不可避免的是大大增加了整個(gè)系統(tǒng)的部署復(fù)雜性。想一下,在LIVE上,我們可能有20個(gè)WEB服務(wù)器,10個(gè)APP服務(wù)器(我們以前是2:1這樣進(jìn)行配置的,服務(wù)按照類(lèi)型和資源不同放在不同的APP服務(wù)器,WEB服務(wù)器CPU特別強(qiáng),APP服務(wù)器是廉價(jià)服務(wù)器,有足夠大的內(nèi)存,對(duì)于WEB程序來(lái)說(shuō)確實(shí)沒(méi)什么大的CPU計(jì)算,服務(wù)也就是緩存比較厲害)。10個(gè)APP服務(wù)器上放100個(gè)服務(wù),就產(chǎn)生了100個(gè)端點(diǎn)地址。開(kāi)發(fā)人員其實(shí)不用考慮服務(wù)在LIVE上怎么部署的,需要架構(gòu)師在部署的時(shí)候協(xié)調(diào)部署團(tuán)隊(duì)一起完成部署工作,架構(gòu)師知道哪個(gè)服務(wù)部署在哪個(gè)服務(wù)器最合理,以哪種信道進(jìn)行部署最合適。部署團(tuán)隊(duì)需要對(duì)各個(gè)服務(wù)器的結(jié)構(gòu)很清楚,也要學(xué)會(huì)使用健康監(jiān)控工具(我前面提到的監(jiān)控服務(wù)運(yùn)行狀態(tài)的工具和異常管理工具來(lái)發(fā)現(xiàn)部署上的問(wèn)題),這就對(duì)部署團(tuán)隊(duì)的要求更高了。實(shí)在不行的話(huà)可以要求開(kāi)發(fā)人員參與,開(kāi)發(fā)人員應(yīng)該沒(méi)權(quán)限直接進(jìn)行服務(wù)的部署,但是有權(quán)使用兩個(gè)工具的,一來(lái)用于排查問(wèn)題,二來(lái)也會(huì)有很大的成就感。
- 服務(wù)監(jiān)控工具以一個(gè)拓?fù)鋱D形式展現(xiàn)整個(gè)網(wǎng)絡(luò)上WEB服務(wù)器、APP服務(wù)器的IP地址、CPU內(nèi)存使用,以及服務(wù)的引用情況和每一個(gè)服務(wù)對(duì)CPU和內(nèi)存的占用,以及服務(wù)的健康情況。監(jiān)控人員24小時(shí)值班負(fù)責(zé)監(jiān)控,出問(wèn)題的時(shí)候及時(shí)重新啟動(dòng)相關(guān)服務(wù)。異常管理工具每天收集各個(gè)系統(tǒng)的異常,開(kāi)發(fā)人員每天上班和下班的時(shí)候查看一次這個(gè)工具,知道自己負(fù)責(zé)的模塊產(chǎn)生了哪個(gè)異常(異常有幾種,一種是程序有BUG,一種是外部有人在攻擊造成的,還有一種是前面說(shuō)的服務(wù)的版本和運(yùn)行問(wèn)題產(chǎn)生的異常)。當(dāng)然,架構(gòu)師也應(yīng)該時(shí)刻關(guān)注這2個(gè)工具,知道整個(gè)系統(tǒng)的健康情況。
- 從網(wǎng)絡(luò)上來(lái)說(shuō),APP服務(wù)器應(yīng)該跨2個(gè)網(wǎng)段,DB服務(wù)器應(yīng)該外部不能直接訪問(wèn),所有數(shù)據(jù)庫(kù)操作都是通過(guò)APP服務(wù)器提供的服務(wù)訪問(wèn)DB的,網(wǎng)站不具有任何連接字符串不能直接訪問(wèn)DB服務(wù)器(不在同一網(wǎng)段)。WEB服務(wù)器和APP服務(wù)器之間應(yīng)該走TCP,如果是跨國(guó)的話(huà)應(yīng)該有VPN鏈路。
- 從軟件架構(gòu)上來(lái)說(shuō),我們以前使用的是.NET Remoting對(duì)內(nèi),Web服務(wù)對(duì)外的方式,中間層以Windows服務(wù)作為載體。對(duì)于.NET 3.5時(shí)代,可以采用WCF+Windows服務(wù)承載的方式。WCF支持元數(shù)據(jù)交換是一個(gè)優(yōu)點(diǎn),另一個(gè)優(yōu)點(diǎn)是方便TCP/HTTP各種綁定的切換,當(dāng)然也可以同時(shí)提供多份綁定。如果是細(xì)粒度服務(wù)的話(huà),可以使用ADO.NET DATA SERVICE+ADO.NET EF的方式直接進(jìn)行提供。表現(xiàn)層可以直接使用ADO.NET DATA SERVICE也可以使用自定義的JSON/XML數(shù)據(jù),不屬于SOA的范疇就不擴(kuò)展了。
總結(jié)一下:
- 對(duì)于ETOWN的應(yīng)用,SOA架構(gòu)是絕對(duì)適合的。
- 實(shí)施SOA,技術(shù)不是問(wèn)題,最大的問(wèn)題還是管理和溝通(協(xié)作)。
- 實(shí)施SOA的話(huà),我們需要重新構(gòu)建一套基礎(chǔ)架構(gòu),提供統(tǒng)一的端點(diǎn)配置管理、異常管理、健康監(jiān)控、契約協(xié)作平臺(tái)等。不然到最后的配置和管理將會(huì)很混亂。
- 我們不需要更多的服務(wù)器,但我們需要更合理的分配服務(wù)器。而且整個(gè)系統(tǒng)的部署架構(gòu)可能隨著時(shí)間的遷移不斷調(diào)整的,合并壓力小的服務(wù),拆散壓力大的服務(wù)。怎么做負(fù)載均衡,這都是一直調(diào)整的。
- 實(shí)施SOA需要開(kāi)發(fā)人員有更好的意識(shí),包括協(xié)作意識(shí),包括架構(gòu)意識(shí)。當(dāng)然,也需要架構(gòu)師能夠參與到每個(gè)項(xiàng)目中去,心中對(duì)業(yè)務(wù)有大局觀。
- 配置可能是復(fù)雜的,需要有工具來(lái)確保這個(gè)復(fù)雜的過(guò)程。服務(wù)和網(wǎng)站怎么配置是很重要的事情,需要架構(gòu)師和開(kāi)發(fā)人員討論決定,不是說(shuō)隨便放上去能用就可以。
- 在做架構(gòu)的時(shí)候要站在較高的角度來(lái)看,眼光要長(zhǎng)遠(yuǎn),暫時(shí)的性能問(wèn)題不一定是問(wèn)題。按照網(wǎng)絡(luò)/磁盤(pán)/內(nèi)存/CPU的層次來(lái)考慮。很多時(shí)候SOA和性能是有沖突的,就像不能一味覺(jué)得ORM性能不好就不去使用。考慮80/20原則,任何東西滿(mǎn)足了80的應(yīng)用就達(dá)到了目的,剩下的20進(jìn)行特殊處理。
暫時(shí)就寫(xiě)這些,大家拍磚。
補(bǔ)充幾點(diǎn):
- 從服務(wù)契約設(shè)計(jì)上來(lái)說(shuō),應(yīng)該讓這個(gè)契約盡可能獨(dú)立,不依賴(lài)于其它的契約。服務(wù)的調(diào)用過(guò)程不能依賴(lài)于服務(wù)本身的狀態(tài),應(yīng)該在任何情況下服務(wù)的作用不會(huì)由環(huán)境所變。
- 雖然說(shuō)是內(nèi)部實(shí)施,但最好數(shù)據(jù)契約的類(lèi)型是標(biāo)準(zhǔn)類(lèi)型,通用類(lèi)型,原生類(lèi)型,方便以后做開(kāi)放API的時(shí)候真正實(shí)現(xiàn)對(duì)外的服務(wù)。其實(shí)SOA強(qiáng)調(diào)松耦合性,因異構(gòu)平臺(tái)協(xié)作的需求產(chǎn)生,強(qiáng)調(diào)一切基于消息,無(wú)關(guān)服務(wù)平臺(tái)。
- SOA的實(shí)現(xiàn)包括業(yè)務(wù)分析、契約規(guī)劃、服務(wù)管理、消費(fèi)者管理、文檔管理、配置管理、迭代整合等重要步驟,不是說(shuō)我要建立A契約就建立,我要消費(fèi)A契約就消費(fèi),要體現(xiàn)在管理中。我一直覺(jué)得SOA不是組件升級(jí)到服務(wù)這么簡(jiǎn)單,軟件開(kāi)發(fā)流程、管理流程、設(shè)計(jì)分析方法、配置管理都會(huì)有巨大的改變,前期準(zhǔn)備要充分。
- 在建立前期需要制作完成一個(gè)基礎(chǔ)的架構(gòu)供開(kāi)發(fā)人員使用。比如說(shuō)是不是需要擴(kuò)展VS內(nèi)建的WEB引用,使得生成的客戶(hù)端代理包括異常處理、端點(diǎn)配置(從配置服務(wù)中獲取)等內(nèi)容。非業(yè)務(wù)相關(guān)異常的收集和發(fā)送等工作應(yīng)該是自動(dòng)的,無(wú)需編碼。由于調(diào)用的復(fù)雜性,服務(wù)可能還會(huì)調(diào)用服務(wù),在部署的時(shí)候配置問(wèn)題很難察覺(jué),所以其中的異常處理非常重要。
- 項(xiàng)目完成后的代碼審閱需要對(duì)項(xiàng)目中用到的服務(wù)進(jìn)行逐一檢查,如果有改變需要在拓?fù)鋱D(推薦有專(zhuān)門(mén)管理軟件來(lái)維護(hù)這個(gè)拓?fù)鋱D,并且還能檢查各個(gè)節(jié)點(diǎn)的健康狀態(tài))中進(jìn)行修改。必要的話(huà)還可以為每一個(gè)節(jié)點(diǎn)實(shí)現(xiàn)信任機(jī)制,得不到信任的消費(fèi)者將不能消費(fèi)。甚至這個(gè)工具可以和SHAREPOINT結(jié)合,也提供文檔的管理。
- 最理想的方式是實(shí)現(xiàn)服務(wù)的自動(dòng)部署,全部依靠管理工具來(lái)完成,因?yàn)樵?a href=/yuedu/fuwuqi/ target=_blank class=infotextkey>服務(wù)器上安裝Windows服務(wù),需要復(fù)制文件、卸載原來(lái)的服務(wù)、安裝新的服務(wù)、服務(wù)運(yùn)行賬戶(hù)的配置,如果服務(wù)達(dá)到上百個(gè)的話(huà),部署的壓力也比較大。
最后,什么是SOA?個(gè)人覺(jué)得SOA是提供了系統(tǒng)級(jí)的松散組合和重用的基于消息的整合方案。
it知識(shí)庫(kù):我對(duì)SOA的認(rèn)識(shí)以及心得,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。