给公司部门设计的SOA架构
新來老大年前開會(huì)說各位同學(xué),公司業(yè)務(wù)越來越重,未來幾年要成倍增長......,要梳理出一套新架構(gòu),才能更好的支持N萬用戶.....,以后升職加薪當(dāng)上....打敗.....
想想還有點(diǎn)小激動(dòng)呢,于是過年時(shí)樓主趁等待相親妹紙無聊的時(shí)候,反思了目前系統(tǒng)現(xiàn)狀,構(gòu)思設(shè)計(jì)新架構(gòu)如下。
閱讀目錄:
2.1 邏輯架構(gòu)圖?
2.2 解釋說明
3.1 SOA管理中心
3.2 發(fā)布服務(wù)
3.3 訂閱服務(wù)
3.4 采蘑菇示例
4.1 盡可能少的侵入
4.2 服務(wù)自治&&水平擴(kuò)展
4.3 系統(tǒng)升級(jí)降級(jí)
5.1 ClientApi VS ServiceApi
5.2 聚合服務(wù)
5.3 服務(wù)分級(jí)
現(xiàn)有系統(tǒng)
鄙司業(yè)務(wù)比較重,系統(tǒng)也有些年頭,各研發(fā)團(tuán)隊(duì)、系統(tǒng)都比較穩(wěn)定了。所以不差也不太好,總之也能滿足現(xiàn)有需求。但近2年O2O,移動(dòng)互聯(lián)網(wǎng)等大行其道,老大們也都心動(dòng)了,開始磨刀霍霍了。而現(xiàn)有系統(tǒng)應(yīng)對(duì)復(fù)雜的變化,在一些地方頗顯不足:
- 接口沒有統(tǒng)一管理
- 很多組件無法復(fù)用/重復(fù)造輪子
- 模塊間職責(zé)不清,耦合過深
- 聯(lián)調(diào)排查問題比較慢
- 開發(fā)前規(guī)劃不足,形成堆積
- 缺乏API規(guī)范/文檔較少
新架構(gòu)
邏輯架構(gòu)圖:
查看大圖
解釋說明:
- A開頭:是系統(tǒng)級(jí)別,可以獨(dú)立部署。即可寄宿在IIS/WindowsService等上面。
- B開頭:是模塊級(jí)別,不可獨(dú)立部署。相對(duì)獨(dú)立的功能模塊,而又不大,所以依附其他系統(tǒng)或者和多個(gè)模塊組成一個(gè)子系統(tǒng)。模塊級(jí)別在項(xiàng)目中可以分多層,可根據(jù)分?jǐn)?shù)升級(jí)成子系統(tǒng)(見系統(tǒng)升級(jí)降級(jí))。
- C開頭:是組件級(jí)別,不可獨(dú)立部署。大多數(shù)是公共性組件,一般是單獨(dú)類庫存在,以DLL提供使用。一些開源組件也歸到這里,例:Autofac,FluentData。 需要自搭Nuget服務(wù)器,進(jìn)行統(tǒng)一版本管理。
- 字母后面的數(shù)字:是代表服務(wù)的級(jí)別,見服務(wù)分級(jí)。
- 系統(tǒng)通信: 各系統(tǒng)之間盡量走內(nèi)網(wǎng)Wcf/Tcp,對(duì)外合作單位及各移動(dòng)端走WebApi/Http。
- 傳輸格式: Protobuffer、Json。
- 數(shù)據(jù)交換: 優(yōu)先通過數(shù)據(jù)服務(wù)接口,其次SSIS、Job。
- 基礎(chǔ)平臺(tái): 緩存Redis,隊(duì)列RabbitMq等。依賴抽象,框架可替換。
- DB 層: 每個(gè)子系統(tǒng)擁有自己的子DB,原則上不能跨庫讀其他的。
- 高可用 : 子系統(tǒng)自行做負(fù)載,服務(wù)變更通知使用zookeeper。
- 單向2級(jí):只能訂閱服務(wù),不能發(fā)布服務(wù),2級(jí)只能訂閱2級(jí)服務(wù)。
- 定點(diǎn):某個(gè)客戶端只能訂閱某個(gè)服務(wù)端提供的服務(wù)。
系統(tǒng)實(shí)施
SOA管理中心
這是新架構(gòu)的核心部分,主要功能如下:
- 提供發(fā)布/訂閱/ServiceAdapter組件
- 提供Web管理界面
- 對(duì)服務(wù)訪問的各種配置
- 在高峰期對(duì)服務(wù)限流/報(bào)警
- 服務(wù)訪問授權(quán)、描述
發(fā)布服務(wù)
各系統(tǒng)通過Web管理頁面進(jìn)行服務(wù)配置發(fā)布。
也可以通過管理中心提供的組件,進(jìn)行配置發(fā)布:
訂閱訪問服務(wù)
各系統(tǒng)通過管理中心提供的組件,去獲取訂閱的服務(wù),然后通過適配器去訪問接口,服務(wù)變更在心跳里面做:
protected void Application_Start(){//獲取服務(wù)列表var serviceList = ServiceManager.GetServiceList();GlobalService.ServiceList=serviceList;}void Heartbeat(){var serviceList = ServiceManager.GetServiceList();GlobalService.ServiceList=serviceList;}ServiceAdapter.Access(GlobalService.ServiceList[0]);采蘑菇示例
設(shè)計(jì)目標(biāo)
盡可能少的侵入
這點(diǎn)是非常重要的,如果不能很好的重用已有的系統(tǒng)或侵入性太強(qiáng),勢(shì)必會(huì)導(dǎo)致:
- 新架構(gòu)周期過長,長期維護(hù)二套結(jié)構(gòu)。這種情況下,成本太高,不好推行下去或者還未推行就被砍了。
- 開發(fā)人員的抵抗,每個(gè)猿類內(nèi)心都有桀驁的脾氣、造輪子的天賦、重組世界的夢(mèng)想...。如果太復(fù)雜、約束太強(qiáng),天知道你們這群猿類會(huì)干出什么事情!
基于這種考慮,才采用服務(wù)分布式而不是服務(wù)集中式。
- 每個(gè)系統(tǒng)在需要時(shí),去訂閱服務(wù),然后拉取服務(wù)地址/MyNeedServcie.list。
- 然后通過ServiceAdapter訪問服務(wù),ServiceAdapter中會(huì)做權(quán)限等一些校驗(yàn)。
- 在服務(wù)上增加ServiceFilter,Fileter會(huì)做權(quán)限校驗(yàn)及服務(wù)被調(diào)用的信息采集。
- 然后在管理中心添加服務(wù),文檔描述。
好處是:A系統(tǒng)與B系統(tǒng)是直接交互的,服務(wù)調(diào)用不走中轉(zhuǎn)路由,性能也好。而組件的作用僅是輔助性的約束。
服務(wù)自治&&水平擴(kuò)展
由于侵入性較小,所以各個(gè)系統(tǒng)之間的服務(wù)變更,維護(hù)完全由各自研發(fā)團(tuán)隊(duì)維護(hù)。
本系統(tǒng)之間通訊不走服務(wù),直接內(nèi)部調(diào)用。調(diào)用通過ServiceAdapter組件訪問,ServiceAdapter包含對(duì)進(jìn)程內(nèi)、WCF、WebApi等訪問的封裝,這樣便于以后替換成其他服務(wù)。 各服務(wù)在擴(kuò)展上不受管理中心節(jié)制,自行做負(fù)載、增加服務(wù)器即可。
系統(tǒng)升級(jí)降級(jí)
當(dāng)有個(gè)新需要過來時(shí),會(huì)根據(jù)產(chǎn)品是否需要獨(dú)立部署,和現(xiàn)有系統(tǒng)耦合性等因素,來評(píng)估是模塊級(jí)還是系統(tǒng)級(jí)。
對(duì)于舊模塊,根據(jù)重要程度、訪問量等評(píng)估出分?jǐn)?shù)。達(dá)標(biāo)的由模塊抽離出子系統(tǒng),單獨(dú)管理。
同樣對(duì)于舊系統(tǒng),不達(dá)標(biāo)的進(jìn)行降級(jí)處理,縮小成模塊整合到其他系統(tǒng)里面。
這塊其實(shí)很重要,如果不對(duì)項(xiàng)目做好評(píng)估的話,往往會(huì)導(dǎo)致一個(gè)系統(tǒng)越來越沉重。最后的結(jié)果就是維護(hù)越來越麻煩,經(jīng)常出問題。最后逼不得已就推到重來,這個(gè)成本就較大些,當(dāng)然成本的事情老大會(huì)考慮更多些。處于這種情況下猿類們會(huì)一邊吐槽著之前的同類渣渣,一邊躍躍欲試準(zhǔn)備大展身手,讓你們瞧瞧什么叫DDD、TDD、設(shè)計(jì)模式......。
前提是在需求開發(fā)時(shí),按模塊進(jìn)行分小層而不是整個(gè)大層,這樣方便協(xié)作開發(fā)和抽取成子系統(tǒng)。
常見問題
ClientApi VS ServiceApi
ClientApi這個(gè)在前期用的比較多的辦法,優(yōu)點(diǎn)很明顯:簡單快捷,從Nuget上安裝引用即可,但這樣后期引發(fā)的問題會(huì)越來越多。
就拿緩存Redis來說,多個(gè)系統(tǒng)都使用客戶端直接訪問Redis服務(wù)器。如果有個(gè)系統(tǒng)連接數(shù)忘記關(guān)閉,就會(huì)影響整個(gè)大系統(tǒng),原因就是Client權(quán)限過大,客戶端是可以對(duì)redis服務(wù)器直接進(jìn)行操控。這種情況下redis服務(wù)器本身是暴露在外的,哪怕客戶端封裝的再好也不行,只要研究下通信協(xié)議規(guī)范,就可以自己寫個(gè)客戶端連(參見:c#實(shí)現(xiàn)redis客戶端(一))。 這個(gè)通信期間無法管控,無法做攔截,同樣隊(duì)列等其他也是同樣情況。
ServiceApi:
這里在中間加了一層,在緩存系統(tǒng)里面做管控,同樣依賴抽象,Redis可替換。緩存系統(tǒng)以服務(wù)的形式發(fā)布給其他系統(tǒng)使用。 避免不了的就是性能有損耗,當(dāng)然這個(gè)損耗可以通過一些手段減小。
聚合服務(wù)
服務(wù)的顆粒度一直是SOA設(shè)計(jì)的頭疼事情。太粗了就很難復(fù)用,太細(xì)了需要多次往返交互,其性能、事務(wù)處理都是個(gè)問題。 比如下訂單服務(wù),這個(gè)過程中包含創(chuàng)建用戶資料,生成預(yù)訂單、支付訂單,更新賬務(wù)關(guān)系,更新庫存等一系列的操作。這是個(gè)粗粒度服務(wù),里面包含若干子系統(tǒng)的提供的細(xì)粒度服務(wù)。 粗粒度服務(wù)下,多個(gè)子系統(tǒng)避免不了互相交互,長久下去會(huì)讓系統(tǒng)過于沉重,變得職責(zé)混亂。
服務(wù)設(shè)計(jì)準(zhǔn)則就是讓服務(wù)高內(nèi)聚,服務(wù)之間松耦合、邊界清晰。所以需要抽離出一個(gè)聚合服務(wù)系統(tǒng),它專門負(fù)責(zé)把各系統(tǒng)提供的細(xì)粒度服務(wù)進(jìn)行整合,提供給前端使用。而其他各個(gè)系統(tǒng)只做自己職責(zé)之內(nèi)的事情。 在聚合服務(wù)系統(tǒng)中,方便我們更合理的把控服務(wù)的顆粒度,提高服務(wù)復(fù)用。
服務(wù)分級(jí)
多個(gè)研發(fā)團(tuán)隊(duì)協(xié)作時(shí),很難每個(gè)人都對(duì)全部業(yè)務(wù)熟悉。所以為了避免服務(wù)調(diào)用混亂,甚至循環(huán)依賴調(diào)用,增加了對(duì)服務(wù)的分級(jí)。
按圖中所示,1級(jí)服務(wù)不能調(diào)2級(jí)服務(wù),即低級(jí)不能調(diào)高級(jí),高級(jí)可調(diào)低級(jí),同級(jí)互相可調(diào)。
這個(gè)級(jí)別針對(duì)單個(gè)服務(wù)而分的。比如有個(gè)更新庫存服務(wù),它沒有外部依賴的服務(wù),只是更新自己的DB,這樣就可以把它劃分為1級(jí)服務(wù)。 而聚合服務(wù)系統(tǒng)中有個(gè)下訂單粗粒度服務(wù),它內(nèi)部調(diào)用更新庫存服務(wù),那么它就是2級(jí)服務(wù)。很明顯這里的1級(jí)不應(yīng)該調(diào)用2級(jí),對(duì)服務(wù)分級(jí)也是這個(gè)目的。
總結(jié)心得
- 好架構(gòu)是不斷進(jìn)化來的
- 盡可能考慮到每個(gè)細(xì)節(jié)
- 注重整體平衡性,而非局部最優(yōu)
- 依賴抽象,而不是具體哪個(gè)框架技術(shù)
- 先考慮人、資源,在考慮用哪個(gè)技術(shù)
- 跟妹紙相處時(shí)不要想程序那點(diǎn)事
SOA相關(guān)資料整理分享
轉(zhuǎn)載于:https://www.cnblogs.com/mushroom/p/4298461.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的给公司部门设计的SOA架构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 互联网组织的未来:剖析GitHub员工的
- 下一篇: 免插件为WordPress文章中标签添加