作者 | Tomasz Nurkiewicz
譯者 | 李騰輝
策劃 | 信遠(yuǎn)
微服務(wù)不能“包治百病”。
時下微服務(wù)是一個不錯的架構(gòu),它具備模塊化、可伸縮和高容錯這些優(yōu)點。許多公司都采用微服務(wù)架構(gòu)并取得了巨大的成功,自然而然地,如果你正開始一個新項目,微服務(wù)似乎是最佳選擇。
然而,大多數(shù)采用微服務(wù)取得成功的公司并不是一開始就選擇了這種架構(gòu)。以Airbnb和Twitter為例,他們在單體應(yīng)用過于龐大之后才選擇了微服務(wù)路線,現(xiàn)在也仍在解決由此帶來的復(fù)雜性。即使是大公司也仍在尋找使用微服務(wù)的最佳方法。所以說,微服務(wù)是一把雙刃劍,需要權(quán)衡利弊。
從單體應(yīng)用遷移到微服務(wù)也絕不是一項簡單任務(wù),未經(jīng)過測驗,便采用微服務(wù)構(gòu)建一個新產(chǎn)品則更加復(fù)雜。只有在充分評估了替代方案之后,才應(yīng)該認(rèn)真考慮是否使用微服務(wù)架構(gòu)。
一、 微服務(wù)僅適用于成熟產(chǎn)品
關(guān)于從頭開始使用微服務(wù),馬丁·福勒(Martin Fowler)總結(jié)道:
1.幾乎所有成功的微服務(wù)都是從一個過于龐大而不得不拆分的單體應(yīng)用開始的。
2.幾乎所有從頭開始以微服務(wù)構(gòu)建的系統(tǒng),最后都會因嚴(yán)重的問題而失敗。這種情況導(dǎo)致許多人認(rèn)為,就算你確信你的應(yīng)用將快速發(fā)展壯大,也不應(yīng)該一開始便采用微服務(wù)。
初版設(shè)計很難優(yōu)化得很好,新產(chǎn)品的前幾次迭代重點在于尋找用戶的真正痛點。因此,成功取決于保持敏捷并能快速優(yōu)化和重構(gòu)。在這方面,微服務(wù)就比單體應(yīng)用差得多。如果你沒有把握設(shè)計好最初的方案,就采用了微服務(wù),那么你的啟程之路將更加困難,因為重構(gòu)微服務(wù)比重構(gòu)單體應(yīng)用要困難得多。
二、你是否在初創(chuàng)公司或者開發(fā)全新項目?
作為一家初創(chuàng)公司,你已經(jīng)在爭分奪秒,在未知的噩耗來臨之前努力尋找突破口。此時你不太需要關(guān)注擴展性(可能幾年之內(nèi)都不需要),那么為什么要使用復(fù)雜的架構(gòu)而忽視客戶的需求呢?
在開發(fā)全新項目時也有類似的情況,這些項目不受前期工作的限制,更沒有任何決策包袱。《構(gòu)建微服務(wù):設(shè)計細(xì)粒度的系統(tǒng)》一書的作者山姆·紐曼(Sam Newman)表示,用微服務(wù)構(gòu)建一個全新的項目非常困難:
我仍然堅信,對現(xiàn)有的舊系統(tǒng)進(jìn)行劃分要比在全新的系統(tǒng)容易得多。你有更多可供幫助的資源,比如你有可供查閱的代碼,你可以與使用和維護(hù)系統(tǒng)的人員交流討論,你也知道一個“好”的系統(tǒng)是什么樣的——基于當(dāng)前穩(wěn)定運作的系統(tǒng)進(jìn)行改變,讓你更容易知道你在哪里做錯了,你的決策是否過于激進(jìn)。
三、微服務(wù)不是本地部署的最佳選擇
由于所有部件都是動態(tài)變化的,微服務(wù)部署需要搭配更強大的自動化機制。在常規(guī)環(huán)境下,我們可以依靠持續(xù)部署管道(continuous deployment pipelines)來完成工作——任務(wù)開發(fā)者部署微服務(wù),消費端盡管使用線上服務(wù)就可以了。
然而這并不適用于本地環(huán)境,如果開發(fā)者發(fā)布一個包,需要消費端自行在其本地環(huán)境上部署和配置其他的服務(wù),這使得部署變得更具挑戰(zhàn)性。
確切的說,開發(fā)本地微服務(wù)應(yīng)用也是可行的,正如Semaphore(一個CI/CD平臺)也提供了本地化部署模式。然而,在這個過程中我們需要克服幾個挑戰(zhàn):
1.本地微服務(wù)的版本控制規(guī)則需要更加嚴(yán)格,你必須跟蹤參與發(fā)布的每個單獨的微服務(wù)。
2.你必須進(jìn)行完整的集成和端到端測試,因為你無法在生產(chǎn)環(huán)境中進(jìn)行測試。
3.如果不能直接訪問生產(chǎn)環(huán)境,對微服務(wù)應(yīng)用進(jìn)行故障排查會困難得多。
四、你的單體應(yīng)用也許還能用
每個軟件都有自己的生命周期。你可能想廢棄一個單體應(yīng)用,因為它很舊并且很復(fù)雜。但折騰一個系統(tǒng)也許費力不討好,如果稍加努力,你也許可以榨出當(dāng)前系統(tǒng)的更多價值,讓他多用幾年。
只有在這兩種情況下,微服務(wù)重構(gòu)才是不得不做的選擇:
1.代碼混亂:在不破壞其他功能的情況下,很難在原代碼基礎(chǔ)上進(jìn)行更改和添加新功能
2.性能因素:你在擴展單體應(yīng)用時遇到了瓶頸
五、模塊化單體
開發(fā)人員想要避免采用單體架構(gòu)的一個常見原因是,單體更容易變成一坨“代碼屎山”。那時很難再添加新功能,因為一切都是相互關(guān)聯(lián)的。
但是單體不一定是一團糟。以Shopify為例:他的代碼行數(shù)超過300萬行,是世界上最大的Rails單體應(yīng)用之一。但有一點,系統(tǒng)過于龐大會給開發(fā)人員帶來許多痛苦:
應(yīng)用非常脆弱,新的代碼會產(chǎn)生許多意想不到的影響。作出一些更改可能會引發(fā)一連串無關(guān)的測試用例失敗。例如,計算運費和計算稅率復(fù)用了一些代碼,那么更改計算稅率代碼的同時可能會影響運費計算的結(jié)果。這是高耦合和缺乏邊界的結(jié)果,也導(dǎo)致測試用例難以編寫,并且在CI上運行得非常緩慢。
Shopify沒有選擇將整個單體應(yīng)用重寫為微服務(wù),而是選擇了模塊化作為解決方案。
模塊化有助于設(shè)計更好的單體或者微服務(wù)。如果沒有認(rèn)真地定義好模塊,我們要么陷入傳統(tǒng)的分層式單體(大泥球),或者更差的結(jié)果,成了分布式單體應(yīng)用,它同時具備單體和微服務(wù)兩者的缺點。
模塊化的工作量很大,但它也帶來了巨大的價值,使開發(fā)可以更加直接。新開發(fā)人員在開始變更代碼之前不必了解整個應(yīng)用,一次只需要熟悉一個模塊。良好的模塊化可以使一個大單體更好上手。
模塊化是切換到微服務(wù)之前的必要步驟,并且有可能是更好的解決方案。與微服務(wù)類似,模塊化單體應(yīng)用通過將代碼拆分為一些獨立的模塊來解決代碼耦合的問題。與微服務(wù)通過網(wǎng)絡(luò)進(jìn)行通信不同,單體應(yīng)用中的模塊通過內(nèi)部API調(diào)用進(jìn)行通信。
分層式單體對比模塊化單體,模塊化單體具有微服務(wù)的許多特征,卻沒有微服務(wù)面臨的諸多挑戰(zhàn)。
六、單體應(yīng)用也能擴展
另一個關(guān)于單體應(yīng)用的誤解是它們無法擴展。如果你遇到性能問題并認(rèn)為微服務(wù)是唯一的出路,可以參考Shopify的案例,在音頻領(lǐng)域Shopify已經(jīng)在超大規(guī)模上構(gòu)建了一個可靠的單體應(yīng)用。
架構(gòu)和技術(shù)棧將決定如何優(yōu)化單體應(yīng)用,在做好模塊化劃分之后,可以利用云原生技術(shù)進(jìn)行擴展:
1.部署單體應(yīng)用的多個實例,并使用負(fù)載均衡器來分配流量
2.使用CDN分發(fā)靜態(tài)資源和前端代碼
3.使用緩存來減少數(shù)據(jù)庫負(fù)載
4.使用邊緣計算(edge computing)或者無服務(wù)調(diào)用(serverless function)來實現(xiàn)高需求功能
七、如果系統(tǒng)可高效工作,不要輕易嘗試改變
如果我們將生產(chǎn)力衡量標(biāo)準(zhǔn)定義為每時間單位實現(xiàn)了多少個有價值的功能,那么在生產(chǎn)力值很高時,切換架構(gòu)幾乎沒有意義。
由于維護(hù)開銷較大,微服務(wù)最初是生產(chǎn)力較低的架構(gòu),隨著單體的增長,系統(tǒng)變得更加復(fù)雜,并且更難添加新功能。微服務(wù)只有在交叉點之后才會獲得更高的生產(chǎn)力。
誠然,有些事情最終還是要做,但那可能是幾年后才考慮的事。到那時,需求可能已經(jīng)發(fā)生改變——誰知道那時候是否還會出現(xiàn)新的架構(gòu)模型呢?
八、布魯克斯定律和開發(fā)人員生產(chǎn)力
在《人月神話(The Mythical Man Month)》一書中,弗雷德里克·布魯克斯(Frederick P. Brooks, Jr.)曾說:“在軟件項目后期增加人力,會讓交付時間更晚”。發(fā)生這種事是因為必須先對新人員進(jìn)行指導(dǎo),然后才能在復(fù)雜的代碼上進(jìn)行開發(fā)。此外,隨著團隊的壯大,溝通成本也會增加,使得組織決策更加困難。
在大型軟件開發(fā)時,布魯克斯定律指出,在軟件項目后期增加人力只會讓花費的時間更長。微服務(wù)是減少定律影響的一種方法。然而,這種效果只能在復(fù)雜而龐大的代碼庫中才能體現(xiàn),因為在這種情況下,我們無法將開發(fā)劃分為各自獨立的任務(wù)。
在使用微服務(wù)之前,你必須考慮布你的單體應(yīng)用是否正在被魯克斯定律所影響。過早地切換到微服務(wù)不會增加更多的價值。
九、你準(zhǔn)備好進(jìn)行切換了嗎?
在開始切換微服務(wù)之前,除了準(zhǔn)備好你的單體之外,你還必須滿足以下條件:
1.為自動化部署設(shè)置好持續(xù)集成和持續(xù)部署(CI/CD)
2.實現(xiàn)快速配置以便按需構(gòu)建基礎(chǔ)架構(gòu)
3.了解云原生技術(shù)棧,包括容器化、K8S、無服務(wù)
4.熟悉領(lǐng)域驅(qū)動設(shè)計(DDD, Domain-Driven Design),測試驅(qū)動開發(fā)(Test-Driven Development),行為驅(qū)動開發(fā)(Behavior-Driven Development)
5.團隊重組,以便跨職能溝通消除信息孤島,采用扁平化管理以激發(fā)創(chuàng)新
6.培養(yǎng)DevOps文化,使開發(fā)人員和運維工作得更加契合
改變組織的文化可能需要數(shù)年時間,學(xué)習(xí)所有的必備知識也許需要數(shù)月時間,如果沒有做好準(zhǔn)備,切換到微服務(wù)是注定無法成功的。
十、總結(jié)
我們可以用一句話總結(jié)上面關(guān)于切換到微服務(wù)的討論:除非你有充分的理由,否則不要輕易去做。那些毫無準(zhǔn)備、沒有可靠設(shè)計就使用微服務(wù)的公司,都將經(jīng)歷一段非常艱難的時期。你需要建設(shè)好技術(shù)文化氛圍,做好技術(shù)儲備,再去考慮微服務(wù)。
同時,如果你的系統(tǒng)運行良好并且仍在以預(yù)期的速度進(jìn)行開發(fā),那么為什么要急于改變呢?
文章內(nèi)容僅供閱讀,不構(gòu)成投資建議,請謹(jǐn)慎對待。投資者據(jù)此操作,風(fēng)險自擔(dān)。
2024年的Adobe MAX 2024發(fā)布會上,Adobe推出了最新版本的Adobe Creative Cloud。
奧維云網(wǎng)(AVC)推總數(shù)據(jù)顯示,2024年1-9月明火炊具線上零售額94.2億元,同比增加3.1%,其中抖音渠道表現(xiàn)優(yōu)異,同比有14%的漲幅,傳統(tǒng)電商略有下滑,同比降低2.3%。
“以前都要去窗口辦,一套流程下來都要半個月了,現(xiàn)在方便多了!”打開“重慶公積金”微信小程序,按照提示流程提交相關(guān)材料,僅幾秒鐘,重慶市民曾某的賬戶就打進(jìn)了21600元。
華碩ProArt創(chuàng)藝27 Pro PA279CRV顯示器,憑借其優(yōu)秀的性能配置和精準(zhǔn)的色彩呈現(xiàn)能力,為您的創(chuàng)作工作帶來實質(zhì)性的幫助,雙十一期間低至2799元,性價比很高,簡直是創(chuàng)作者們的首選。
9月14日,2024全球工業(yè)互聯(lián)網(wǎng)大會——工業(yè)互聯(lián)網(wǎng)標(biāo)識解析專題論壇在沈陽成功舉辦。