新聞中心
最近我們開發(fā)團(tuán)隊(duì)在開發(fā)計(jì)劃中有一個(gè)小停頓,技術(shù)部門認(rèn)為現(xiàn)在是將應(yīng)用從單體架構(gòu)遷移到微服務(wù)的最佳時(shí)機(jī)。

創(chuàng)新互聯(lián)成立于2013年,我們提供高端成都網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、網(wǎng)站定制、成都營銷網(wǎng)站建設(shè)、微信小程序開發(fā)、微信公眾號(hào)開發(fā)、成都網(wǎng)站推廣服務(wù),提供專業(yè)營銷思路、內(nèi)容策劃、視覺設(shè)計(jì)、程序開發(fā)來完成項(xiàng)目落地,為成都發(fā)電機(jī)租賃企業(yè)提供源源不斷的流量和訂單咨詢。
經(jīng)過一個(gè)月的準(zhǔn)備和調(diào)查,我們?nèi)∠诉w移,仍然使用單體模式。對(duì)我們而言,微服務(wù)不僅幫不上忙,反而會(huì)影響到開發(fā)計(jì)劃。
我們了解微服務(wù)大約是在一年前,但是很驚訝地發(fā)現(xiàn)它并不適合我們。本篇文章把我們的經(jīng)歷寫出來,可能會(huì)對(duì)大家有借鑒意義。
發(fā)現(xiàn)問題以及早期妥協(xié)
我們嚴(yán)重依賴第三方
我們的應(yīng)用是整合外部現(xiàn)有產(chǎn)品和業(yè)務(wù)規(guī)則給用戶展現(xiàn)一個(gè)友好界面的 UI??蛻羰且患?UWP App,后臺(tái)有相應(yīng)服務(wù)在第三方域和我們之間交換數(shù)據(jù)。
對(duì)第三方的依賴嚴(yán)重影響我們選擇微服務(wù)。例如,應(yīng)用經(jīng)常要在不同域之間轉(zhuǎn)換功能,使得第三方域看起來像是完全不同的一個(gè)域,如果在我們之間有一個(gè)單一服務(wù)情況還不算太糟。
然而,整個(gè)域交換在分解成多個(gè)微服務(wù)過程中就看起來很怪異了。
是我們的微服務(wù)跟第三方的分解不同嗎?我們復(fù)制了所有服務(wù)的前后端需求嗎?還是我們分解了自己的微服務(wù),仍然需要一個(gè)微服務(wù)從第三方獲取信息?所有這些問題看起來都跟微服務(wù)指南相背離。
我們和第三方合作很緊密,經(jīng)常一起協(xié)作發(fā)布版本。微服務(wù)的好處在于每個(gè)團(tuán)隊(duì)都可以不受影響?yīng)毩l(fā)行服務(wù),而跨公司合作則失去了這種好處。
微服務(wù)另外一個(gè)好處在于,每個(gè)團(tuán)隊(duì)只需要完整設(shè)計(jì)自己的業(yè)務(wù)問題。而我們,作為一個(gè)和第三方完全獨(dú)立的公司團(tuán)隊(duì),這種重構(gòu)看起來不可行。
我們不能有效分離微服務(wù)
我們實(shí)在找不出應(yīng)該從哪個(gè)單體應(yīng)用下手。于是我們?cè)谟蚰P椭g連線,以決定要?jiǎng)?chuàng)建哪些微服務(wù)。
然而,一旦這么開始做,發(fā)現(xiàn)很多共享業(yè)務(wù)邏輯影響著微服務(wù)域的劃分。如果將微服務(wù)劃分的更細(xì)小,只能帶來更多的耦合關(guān)系,到處都需要消息總線,消息可能會(huì)出現(xiàn)大爆炸。
原因在于我們的單體式應(yīng)用是為一個(gè)業(yè)務(wù)邏輯服務(wù)的。我們?yōu)橛脩舴奖銊?chuàng)建了跨域和組的很多工作流,本質(zhì)上,UI 在過去四年中就是將各種東西整合到了一起。
另外,我們還誤解了微服務(wù)如何被隔離,以及低估了服務(wù)之間正確邊界選擇的重要性。
唯一能做到的就是為了實(shí)現(xiàn)一個(gè)標(biāo)準(zhǔn)功能,從而需要將所有相關(guān)微服務(wù)同時(shí)升級(jí),由此要求每個(gè)微服務(wù)都不能被某個(gè)單獨(dú)團(tuán)隊(duì)擁有。
共享微服務(wù)
我們大約有 12 個(gè)開發(fā)人員分布在兩個(gè)功能團(tuán)隊(duì)和一個(gè)支持團(tuán)隊(duì)。工作波動(dòng)性很大,沒有專職負(fù)責(zé)團(tuán)隊(duì)。所有團(tuán)隊(duì)同時(shí)接觸同一批代碼很正常,不能將某個(gè)微服務(wù)指定給一個(gè)團(tuán)隊(duì)。
考慮架構(gòu)時(shí)候一定要記得 Conway's Law,其意思是軟件架構(gòu)會(huì)模仿組織和團(tuán)隊(duì)架構(gòu)增長。
微服務(wù)架構(gòu)對(duì)于不同團(tuán)隊(duì)負(fù)責(zé)不同業(yè)務(wù)邏輯是比較有效的,然而,共享代碼功能的工作模式最好采用單體式架構(gòu)。
平臺(tái)并沒有準(zhǔn)備好
各種問題意味著至少六個(gè)月內(nèi),需要在 IIS 內(nèi)并行運(yùn)行微服務(wù)和單體式應(yīng)用。
我們不會(huì)訪問與微服務(wù)相關(guān)的工具,如容器、Kubernetes、服務(wù)總線、API 網(wǎng)管等,也就意味著與其他微服務(wù)之間通訊有很大障礙。
因此,我們決定每個(gè)微服務(wù)都復(fù)制與存儲(chǔ)層轉(zhuǎn)換相關(guān)讀服務(wù)的共享邏輯。因?yàn)椴荒苷2鸱址?wù),也就意味著必須承擔(dān)大量復(fù)制工作量。
例如,對(duì)于某個(gè)復(fù)雜而且基礎(chǔ)的業(yè)務(wù)邏輯,必須復(fù)制黏貼并維護(hù)至少 4 個(gè)計(jì)劃中的微服務(wù)。
沒有未來清晰圖景
開發(fā)團(tuán)隊(duì)只有六個(gè)月內(nèi)粗略的構(gòu)想,而且業(yè)務(wù)更改也很頻繁(業(yè)務(wù)更改需求也是司空見慣的事情),這些讓微服務(wù)化更加充滿不確定性,因?yàn)榧词乖诙唐谝矡o法預(yù)知會(huì)出現(xiàn)什么鏈接。
微服務(wù)之間的復(fù)雜性會(huì)增加嗎?花了幾個(gè)月分離的服務(wù)會(huì)回到過去嗎?盡管我們今年早些時(shí)候做過一些 PoC,但是因?yàn)闃I(yè)務(wù)需求的更改不得不放棄。
架構(gòu)緊耦合
我們只有一個(gè)很窄的時(shí)間窗口,剛好能把單體式應(yīng)用分解成列出來的微服務(wù),而且沒有冗余時(shí)間應(yīng)付可能出現(xiàn)的改變,也沒有 Plan B,我們被自己給卡住了。
因?yàn)槲覀冊(cè)谟?jì)劃階段就發(fā)現(xiàn)了很多問題和挑戰(zhàn),更別說實(shí)施階段了,開發(fā)團(tuán)隊(duì)非常有壓力。
缺乏經(jīng)驗(yàn)
考慮到風(fēng)險(xiǎn)和時(shí)間壓力,而且架構(gòu)師和實(shí)施專家也都沒有任何特殊經(jīng)驗(yàn),加上沒有標(biāo)準(zhǔn)工具能用,我們只能靠自己來實(shí)施,這些都更加惡化了情況。
和其他微服務(wù)大拿溝通后,他們也都發(fā)出了很多警告,并給出了不少以前并沒有的架構(gòu)建議,指出了我們?cè)谟蚰P椭g畫線的順序。
到目前為止,由于時(shí)間緊任務(wù)重,我們的計(jì)劃包括了很多不同于標(biāo)準(zhǔn)微服務(wù)的妥協(xié)方案。
因?yàn)槿狈<?,這看起來更像一條不歸之路,開發(fā)團(tuán)隊(duì)越來越焦慮。
再次拷問我們的目標(biāo)
是否解決了痛點(diǎn)
一旦前方布滿了困難,就失去了目標(biāo),我們暫停下來,意識(shí)到我們并沒有搞明白為什么要這樣做。
我們沒有列出痛點(diǎn),而且不清楚這樣做是否可以解決痛點(diǎn)。更甚,微服務(wù)有可能會(huì)給我們帶來新的問題。
我們開始反思,我們從中會(huì)獲得什么好處?能解決什么問題?我們召開了更多會(huì)議討論它,但一直沒有明確的答案。
最后,我們發(fā)現(xiàn)在討論微服務(wù)過程中我們忽略了一個(gè)很重要的痛點(diǎn),而且沒有足夠的時(shí)間來解決這個(gè)問題,也就是我們不能考慮微服務(wù)或者其他東西了。
潛在收益是什么
這時(shí)候我們開始反思微服務(wù)一般意義上會(huì)帶來什么好處?
自治
微服務(wù)使得團(tuán)隊(duì)可以控制全棧提供一個(gè)功能。這種區(qū)隔會(huì)減少不同團(tuán)隊(duì)之間協(xié)同的次數(shù),互相不影響對(duì)方的工作。
使團(tuán)隊(duì)更加專注
單體式應(yīng)用中,團(tuán)隊(duì)可以專注于所有任務(wù)。而采用微服務(wù)后,則是某項(xiàng)業(yè)務(wù)流程的專家。
他們會(huì)理解自己區(qū)域內(nèi)的業(yè)務(wù)規(guī)則和需求,知道軟件棧如何搭建,當(dāng)發(fā)生改變時(shí)會(huì)非常有信心完成。
易于擴(kuò)展
有了微服務(wù),可以根據(jù)性能需求擴(kuò)展服務(wù)規(guī)模。而在單體式應(yīng)用中,盡管也可以水平擴(kuò)展服務(wù),但是不能獨(dú)立擴(kuò)展單體應(yīng)用的模塊。
微服務(wù)粒度可以增加或者減少服務(wù)能力。也許當(dāng)發(fā)現(xiàn)性能問題時(shí),可以參與其他工作,或者稍微喘口氣。
易于回滾
每個(gè)功能只需要修改單一微服務(wù),而且可以不影響其他團(tuán)隊(duì)工作進(jìn)行回滾。另外微服務(wù)還可以減少單一錯(cuò)誤對(duì)整個(gè)系統(tǒng)的影響。
易于迭代
如果有一個(gè)擴(kuò)充系統(tǒng)的,每個(gè)發(fā)布都很花時(shí)間并且有風(fēng)險(xiǎn),那么就需要大量工作處理每次發(fā)行時(shí)的問題。
微服務(wù)可以減少溝通時(shí)間和成本,團(tuán)隊(duì)可以各自確定合適時(shí)間。
采用最佳技術(shù)
團(tuán)隊(duì)依賴微服務(wù)可以選擇最佳技術(shù)方案。而單體式卻很難升級(jí)。
易于升級(jí)
大型應(yīng)用升級(jí)都不是一件容易的事情。尤其是要在多個(gè)團(tuán)隊(duì)之間協(xié)作。相互隔離的微服務(wù)可以每次只升級(jí)一個(gè)服務(wù),更容易控制風(fēng)險(xiǎn)。
風(fēng)險(xiǎn)保護(hù)
微服務(wù)可以將頻繁變化和很少變化的服務(wù)分隔開,減少意外發(fā)生的風(fēng)險(xiǎn)。
粒度減小
小型化服務(wù)更易于理解,而且可以保持設(shè)計(jì)一致。對(duì)比來看,單體式應(yīng)用會(huì)因?yàn)椴煌瑘F(tuán)隊(duì)的意見不統(tǒng)一帶來不一致性。
優(yōu)勢(shì)匯總
微服務(wù)有很多優(yōu)勢(shì)。但是我們能從中獲得什么?
最終,對(duì)于無法改變或者妥協(xié)的架構(gòu)只能放棄這些優(yōu)勢(shì)。我們失去了微服務(wù)帶來的隔離性。與第三方的合作減弱了從服務(wù)不相關(guān)性中帶來的好處。
權(quán)衡
大炮打蚊子
微服務(wù)也并不都是優(yōu)點(diǎn),有一長串需要考慮的問題。
例如,日志,監(jiān)控,異常處理,容錯(cuò),回滾,通訊,消息格式,容器,服務(wù)發(fā)現(xiàn),備份,遙測(cè),報(bào)警,跟蹤,工具,共享,文檔,擴(kuò)展,時(shí)區(qū),階段,API 版本,網(wǎng)絡(luò)延遲,健康檢查,負(fù)載均衡,CDC測(cè)試,等等。
如果沒有微服務(wù)平臺(tái),我們要自己面對(duì)所有上面列出來的問題。因?yàn)橛型袋c(diǎn)才要轉(zhuǎn)向微服務(wù),但是不但沒法從中獲益,還要面對(duì)一堆轉(zhuǎn)向微服務(wù)帶來的問題,我們是何苦來呢?
微服務(wù)只是名義
下圖是我們現(xiàn)在單體式應(yīng)用和微服務(wù)的對(duì)比。架構(gòu)上來看,新架構(gòu)很像單體式,各個(gè)組件還是緊耦合,也許我們只是用了微服務(wù)的標(biāo)簽。
單體式一定很差嗎
好像“單體式”就意味著落后,“微服務(wù)”就意味著先進(jìn)。但是從開發(fā)團(tuán)隊(duì)來看,我們的單體式應(yīng)用運(yùn)行良好,基本沒有什么問題。
我們有很好的 CI/CD 配置,易于配置和回滾。分支和測(cè)試策略確保問題都被提前解決。
似曾相識(shí)
此時(shí),似乎有些熟悉的感覺。在我以前從業(yè)經(jīng)驗(yàn)也有過類似的經(jīng)驗(yàn),但從沒稱為微服務(wù),盡管并不完全符合微服務(wù)的規(guī)則,但是的確解決了問題并帶來類似的好處。
5 個(gè)人的小團(tuán)隊(duì)帶領(lǐng) 200 人的開發(fā)者。這是一個(gè)巨大的 C# 應(yīng)用,大概 5% 的工作通過單體式共享,其他的共享兩節(jié)點(diǎn)服務(wù)。
我們也不喜歡單體式,工作起來很慢,編譯,測(cè)試,架構(gòu)改變的很快經(jīng)??吹讲煌耐鲁霈F(xiàn)。
有時(shí)候因?yàn)橐粋€(gè)從未聽過的同事辭職了從而延遲了整個(gè)項(xiàng)目,技術(shù)更新因?yàn)橐驼麄€(gè)公司同步需要幾個(gè)月,Pull 申請(qǐng)需要整個(gè)系統(tǒng)批復(fù)需又要幾個(gè)星期。
同時(shí),有兩個(gè)服務(wù)規(guī)模很小,我們可以很好地控制、部署、架構(gòu)它。一旦有性能問題,會(huì)懷疑實(shí)例數(shù)量直到解決底層問題,很少麻煩其他團(tuán)隊(duì)。
我們團(tuán)隊(duì)主導(dǎo)了前后端開發(fā)語言的選擇??傊?,我們很專注于一個(gè)很窄的業(yè)務(wù)邏輯,每個(gè)人都成為了專家。
技術(shù)之外
越了解微服務(wù),越發(fā)現(xiàn)其不太適合我們。我們是不是太為了技術(shù)而技術(shù)了?
還有很多其他問題沒考慮:
- 有沒有專注業(yè)務(wù)邏輯的團(tuán)隊(duì)?
- 是否能夠清晰劃分域和微服務(wù)?
- 工作在所有團(tuán)隊(duì)之間是否平衡?
- 團(tuán)隊(duì)負(fù)載是否均衡?
- 單體式困難是否被分解到其他工作中?
復(fù)盤
遷移到微服務(wù)是個(gè)大爆炸,大家都停下功能開始想如何分解單體引用,即使前提還不具備。
后來證明這不是個(gè)好方法,有可能還是個(gè)倒退。首先創(chuàng)建所有微服務(wù),然后設(shè)置架構(gòu)并忽略了團(tuán)隊(duì)的架構(gòu)。
假如我們開始時(shí)考慮團(tuán)隊(duì)和業(yè)務(wù)邏輯結(jié)合,等架構(gòu)成熟,并等微服務(wù)自然顯現(xiàn),會(huì)更好。而且新的業(yè)務(wù)需求出現(xiàn),可以直接被放在一個(gè)新服務(wù)中。
強(qiáng)制上微服務(wù),也意味著需要選擇每個(gè)微服務(wù)的大小。一些文章建議每個(gè)微服務(wù)至少按照一個(gè)團(tuán)隊(duì)的支撐設(shè)計(jì)。其他的則建議越小越好,一旦需要更改,很短時(shí)間內(nèi)就可以完成。
領(lǐng)導(dǎo)層決定按照工作域劃分,如果需要再細(xì)分。這個(gè)決定導(dǎo)致上面出現(xiàn)的問題。后來復(fù)盤時(shí)發(fā)現(xiàn)如果等待微服務(wù)自然出現(xiàn),其大小其實(shí)最合適。
取消
隨著預(yù)定時(shí)間一天天臨近,我們團(tuán)隊(duì)持續(xù)發(fā)現(xiàn)越來越多的問題。上線四天后,仍然看不到預(yù)期的效果。于是召開了一次會(huì)議,最終取消了微服務(wù)計(jì)劃。
取代行動(dòng)
微服務(wù)的熱度消散,也就意味著我們沒有做好必要的調(diào)研。拋棄了微服務(wù)后,我們也有精力去調(diào)研其他方案。
最后,我們決定在單體應(yīng)用內(nèi)部劃分成不同項(xiàng)目,更好地劃分了架構(gòu)和耦合關(guān)系。
另外這種架構(gòu)使得域模型更加清晰,使得未來考慮微服務(wù)更容易。
結(jié)論
領(lǐng)導(dǎo)層上微服務(wù)的倉促?zèng)Q定并沒考慮清楚挑戰(zhàn)和目前狀態(tài)。評(píng)估后,發(fā)現(xiàn)微服務(wù)并不適合我們,需要更多的妥協(xié)。
這些折衷方案把微服務(wù)帶來的好處都抵消掉了。微服務(wù)并不考慮非技術(shù)因素,例如團(tuán)隊(duì)結(jié)構(gòu)和工作量。
幾個(gè)月調(diào)研后,我們拋棄了微服務(wù)嘗試,決定對(duì)已有的單體式應(yīng)用做一些更適合的微調(diào)。
名稱欄目:為什么我們要放棄遷移到微服務(wù)?
文章起源:http://fisionsoft.com.cn/article/dpheshs.html


咨詢
建站咨詢
