停!你不需要微服务
王歡
Golang開發(fā)者、DockerOne社區(qū)譯者
讀完需要
8
分鐘速讀僅需 3 分鐘
現(xiàn)在已經(jīng)是2020年了。如果你想要從我這邊了解什么是微服務(wù),那么這篇文章可能不適合你,你可以把寶貴的時(shí)間花在別的地方尋找相關(guān)信息。但是如果你正在經(jīng)受各種微服務(wù)成功案例的洗禮并且被迫去使用微服務(wù)這款“靈丹妙藥”;那就繼續(xù)讀下去。不過開始時(shí)我們先說點(diǎn)讓人失望的地方。
盡管想寫這篇關(guān)于微服務(wù)的文章有一段時(shí)間了,但是直到最近我和一些朋友交流過后才真正的著手去把它寫下來的。最近我受邀參加了一個(gè)法定人數(shù)會議(quorum),并討論了一個(gè)有趣的問題。“什么是微服務(wù)以及我們應(yīng)該使用這種架構(gòu)作為解決方案嗎?”
問題的第一個(gè)部分比較好回答,第二部分就不好回答了。不過經(jīng)過幾分鐘的討論,有幾點(diǎn)是比較清晰的。
受益人(beneficiaries)打算把微服務(wù)架構(gòu)應(yīng)用到他們以后的產(chǎn)品上;并且他們希望得到與會人員的肯定。
參加會議的人有很大一部分不是技術(shù)相關(guān)的。并且會議中對技術(shù)的討論越多,這些人就越顯得不相關(guān)。
會議中長時(shí)間的沉默以及對相關(guān)問題缺乏相應(yīng)的提問表明許多人對Web服務(wù)都不了解,更別提微服務(wù)了。
我不是責(zé)備他們對Web服務(wù)的不了解,或者微服務(wù)能給他們帶來哪些好處和壞處。畢竟他們也有自己擅長的工作,而我不擅長的。他們只是跳上了不知道能給他們帶來哪些影響的微服務(wù)這趟車上。
我第一次聽到“微服務(wù)”這個(gè)詞是在2013年,一個(gè)YouTube視頻上,講的是關(guān)于Netflix服務(wù)架構(gòu)的。視頻里面說了很多微服務(wù)相關(guān)的信息,但是我毫不猶豫的都跳過了。這對于一個(gè)當(dāng)時(shí)想要進(jìn)入設(shè)計(jì)領(lǐng)域的人來說,內(nèi)容太多了。但是很快我就遇到了困擾,因?yàn)樾马?xiàng)目計(jì)劃書要求使用微服務(wù)。這個(gè)項(xiàng)目的設(shè)計(jì)很優(yōu)秀,并且現(xiàn)在仍然是我手上最優(yōu)秀代碼庫中的一員。
誠實(shí)點(diǎn)說,最大化模塊設(shè)計(jì)讓我避免了很多坑。并且當(dāng)時(shí)我還僅僅是一個(gè)初出茅廬的開發(fā)人員,跳過運(yùn)維開發(fā)(DevOps),還額外加了一個(gè)密度(density)層。時(shí)間快速向前推進(jìn)五年,這個(gè)時(shí)候我和一幫新的同事忙于一個(gè)新的產(chǎn)品。并且我每天要面對許多由于不好的微服務(wù)設(shè)計(jì)引起的問題,而且還要耦合業(yè)余的運(yùn)維開發(fā)策略。不過這些問題很快就解決了,但是我又面臨微服務(wù)的脆弱性問題。最后我只能憑著自己的經(jīng)驗(yàn)去分析整個(gè)架構(gòu)。亡羊補(bǔ)牢,為時(shí)未晚。
看到微服務(wù)既扮演正派角色又扮演反派角色,我勸解自己作為反派角色的擁護(hù)者。如果你是一個(gè)架構(gòu)師或者設(shè)計(jì)者并且打算把微服務(wù)作為默認(rèn)架構(gòu),我強(qiáng)烈建議你問自己幾個(gè)問題。
1
? ?
你的程序大到足夠分解為微服務(wù)嗎?
承認(rèn)吧。不是所有的程序都足夠大到需要分解為更小的服務(wù)。正如微服務(wù)名字所暗示的,它是一個(gè)由更小的并且用于完成某個(gè)特定功能的獨(dú)立服務(wù)的集合。理想情況下,每個(gè)服務(wù)都是完全獨(dú)立的應(yīng)用程序。
這是微服務(wù)與單體服務(wù)每行代碼成本(Cost per Line of Code)的比較圖。微服務(wù)會帶來更大的成本,即使這個(gè)微服務(wù)是個(gè)很輕量級的,原因是由于它在人力和計(jì)算成本方面需要一個(gè)最小的資源。每個(gè)人都要考慮成本,如果你不考慮,那么你可能就不應(yīng)該做決策。
當(dāng)然,你的代碼庫未來會不斷增長,并且它本身也可能會添加一個(gè)新域(domain)。但是你要永遠(yuǎn)記住一條,當(dāng)你需要的時(shí)候,一個(gè)設(shè)計(jì)良好的代碼庫總是能夠切換到微服務(wù)。
2
? ?
你真的需要伸縮(scale)應(yīng)用中的不同組件嗎?
我們假設(shè)一下。你的產(chǎn)品負(fù)責(zé)人向你提出了一個(gè)HRMS應(yīng)用程序的想法,這個(gè)程序需要處理一個(gè)擁有10k雇員的組織。作為一個(gè)技術(shù)愛好者的你立馬想出了一個(gè)解決方案:微服務(wù)架構(gòu)。
當(dāng)然,這是一個(gè)極端的例子,但是你能理解這個(gè)點(diǎn)!
使用微服務(wù)架構(gòu)的另一個(gè)主要優(yōu)點(diǎn)是伸縮單個(gè)組件很簡單。我們可以發(fā)現(xiàn)許多應(yīng)用程序都需要對組件進(jìn)行單獨(dú)的伸縮,但是你的應(yīng)用程序真的需要這個(gè)功能嗎?
3
? ?
你是否有跨服務(wù)的事務(wù)?
現(xiàn)在,這是個(gè)即艱難又要講究策略的選擇。跨多個(gè)服務(wù)的事務(wù)對整個(gè)架構(gòu)來說是個(gè)不利因素。解決跨服務(wù)的事務(wù)意味著,服務(wù)之間的互斥鎖,一系列很難追蹤的死鎖以及競爭條件都會嚴(yán)重影響服務(wù)的健康運(yùn)行;并且有時(shí)甚至?xí)こ處熢斐珊艽笥绊憽?/p>
從定義上來看REST服務(wù)是無狀態(tài)的。并且它們也不應(yīng)該參與到跨多個(gè)服務(wù)的事務(wù)中。在高性能世界中,兩階段提交(2PC)是不必要之惡。并且SAGA模式僅僅是加了一個(gè)你不了解的復(fù)雜層。
由于微服務(wù)使用了去中心化的數(shù)據(jù)管理,所以產(chǎn)生了最終一致性問題。單體應(yīng)用中,你可以在一個(gè)事務(wù)中一次性更新許多東西。微服務(wù)需要更新多個(gè)資源的時(shí)候,使用分布式事務(wù)不是很好(有充分的理由)。所以現(xiàn)在,開發(fā)者需要意識到一致性問題,并且在代碼運(yùn)行出現(xiàn)不可挽回的錯(cuò)誤之前能夠及時(shí)的發(fā)現(xiàn)不一致的問題——Martin Fowler。
跨多服務(wù)的事務(wù)可行嗎?
是的,絕對可行的。
但是,是否有必要實(shí)現(xiàn)一個(gè)通過多個(gè)無狀態(tài)服務(wù)的鏈?zhǔn)讲僮?#xff1f;
可能沒必要!
4
? ?
服務(wù)之間是否需要頻繁的通信?
在傳統(tǒng)的單體服務(wù)中,每個(gè)模塊就是微服務(wù)實(shí)例的表現(xiàn)形式。模塊之間的通信都是使用內(nèi)存并且延遲接近于0。微服務(wù)的引入意味著通信從使用內(nèi)存轉(zhuǎn)移到了使用網(wǎng)絡(luò)。
目前市面上有許多成熟的解決方案,但是他們都有一個(gè)共同的代價(jià)——延遲。從使用內(nèi)存轉(zhuǎn)移到基于網(wǎng)絡(luò)的通信會讓你的延遲從以納秒為單位變?yōu)橐晕⒚顬閱挝弧O胂笠幌?#xff0c;有三個(gè)不同的服務(wù)通過網(wǎng)絡(luò)互相通信。假設(shè)每個(gè)服務(wù)調(diào)用需要100毫秒(在負(fù)載很高的情況下這個(gè)是很正常的事情),那么僅僅在網(wǎng)絡(luò)上就要花費(fèi)300毫秒。
另外有些應(yīng)用程序天然的就與組件和服務(wù)緊密的集成在一起。比如在需要實(shí)時(shí)處理數(shù)據(jù)的應(yīng)用中,額外的通信層可能會導(dǎo)致一個(gè)嚴(yán)重的后果。想象一下,在外科手術(shù)服中或者航空交通管制中出現(xiàn)通信延遲會出現(xiàn)什么后果。
5
? ?
其他補(bǔ)充
復(fù)雜度的增加——當(dāng)然,復(fù)雜度不好量化,并且在相對情況下才有可比性。盡管微服務(wù)最初的目的就是通過把單個(gè)應(yīng)用分解為更小的多個(gè)模塊來降低復(fù)雜度,但是在部署和維護(hù)方面微服務(wù)架構(gòu)本身就很復(fù)雜。
部署(distribution)成本——微服務(wù)都是獨(dú)立的分布式系統(tǒng)。相同部分的部署都會有成本。比如你的單體應(yīng)用之前都是部署在一個(gè)大的虛擬機(jī)上或者首選的容器上,但是微服務(wù)都是獨(dú)立部署(理想情況下)在不同的虛擬機(jī)或者容器上。雖然它們相對比較小,但是做個(gè)數(shù)學(xué)計(jì)算就知道了。并且我們還沒有把微服務(wù)的編排和維護(hù)算在里面。
運(yùn)維開發(fā)的適配——這個(gè)要根據(jù)自身的情況來看,可能有利也可能有害。運(yùn)維開發(fā)是一個(gè)已經(jīng)被廣泛接受的并且也是一個(gè)被證實(shí)可操作的解決方案。但是如果你所在的團(tuán)隊(duì)很小,那么組建一個(gè)運(yùn)維開發(fā)團(tuán)隊(duì)帶來的問題要比好處大。但是有一件事是可以確定的,如果你不投入一個(gè)運(yùn)維開發(fā)團(tuán)隊(duì),那么你就沒法對微服務(wù)進(jìn)行有效的維護(hù)和監(jiān)控。
緊密集成——有些應(yīng)用程序本身就需要緊密的耦合。為了適應(yīng)微服務(wù)架構(gòu)而去解耦他們可能會產(chǎn)生嚴(yán)重問題。
經(jīng)驗(yàn)不足——經(jīng)驗(yàn)不足是個(gè)很嚴(yán)重的問題并且它們不僅僅局限在SOA這塊。對于持有抽象定義的微服務(wù)來說,可能會產(chǎn)生更嚴(yán)重的問題。如果你的微服務(wù)是按照順序部署的,并且你的服務(wù)依賴其他服務(wù),那么如果你依賴的一個(gè)服務(wù)掛掉了,你自己的服務(wù)此時(shí)崩潰了,這個(gè)時(shí)候再去處理就會顯得很晚了。
端到端測試——典型的單體應(yīng)用可以讓你啟動并且?guī)缀趿ⅠR運(yùn)行測試。對于互相依賴的多個(gè)服務(wù),如果沒有可靠的編排,那么測試就會被延遲。
混亂的數(shù)據(jù)合約(contracts)——在同一個(gè)團(tuán)隊(duì)中制定和保持?jǐn)?shù)據(jù)合約和在不同團(tuán)隊(duì)之間共享有著極大的不同。并且當(dāng)你使用微服務(wù)時(shí),你的團(tuán)隊(duì)有可能都沒在用;更不必說讓他們都使用相同的編程語言。為特殊需要制定相應(yīng)的數(shù)據(jù)合約也會消耗你的時(shí)間和精力。
遺留代碼庫——對于我們中的大部分人來說,處理遺留的代碼庫就是每天的日常活動。大部分公司都是這種情況。快速變化的新技術(shù)不斷的推動著我們向前走,同時(shí),它也把我們與遺留代碼庫隔離的越來越遠(yuǎn)。
你確信你剛剛開發(fā)的RabbitMQ框架能夠和你之前部署在IBM AIX服務(wù)器上的應(yīng)用程序工作很好嗎?
調(diào)試的痛苦——每個(gè)服務(wù)都有自己的日志文件。更多的服務(wù)=更多的日志文件。
6
? ?
總結(jié)
我有告訴過你“不要使用微服務(wù)”嗎?
絕對沒有!
我們經(jīng)常會聽到微服務(wù)一個(gè)比較好的優(yōu)點(diǎn)是,它們解決了之前我們都認(rèn)為解決不了的問題。Netflix使用微服務(wù)構(gòu)建系統(tǒng)已經(jīng)成為了一個(gè)好的典范。當(dāng)然成功的案例不僅僅只有Netflix。Uber, SoundCloud,以及偉大的亞馬遜都是成功的一員。另外也不要認(rèn)為成功的案例僅僅局限于消費(fèi)應(yīng)用程序。我曾在美國一家醫(yī)療保健巨頭工作過,每一次打開源代碼看到他們在設(shè)計(jì)上的創(chuàng)新(possibilities),都會讓我很著迷。
如果五年前你就入了微服務(wù)的坑,那么我不會譴責(zé)你的盲從。畢竟時(shí)間不一樣了,我們現(xiàn)在能做的就是誠實(shí)的看待它。但是現(xiàn)在是2020年了,我們已經(jīng)踩過太多的坑并且我們身邊也有很多這樣的案例。不必要的引入微服務(wù)架構(gòu),將會導(dǎo)致不良的代碼變成不良的基礎(chǔ)架構(gòu)。
我喜歡一個(gè)充滿熱情的程序員。我曾經(jīng)是并且現(xiàn)成依然是其中的一員。他們堅(jiān)持自己所做的事并且能夠超預(yù)期的解決別人的問題。但是在做決策方面就很難保持這樣的熱情,畢竟那是需要一點(diǎn)運(yùn)氣成分在里面的。很抱歉讓你失望了。微服務(wù)不應(yīng)該作為你的默認(rèn)選擇。它們不是你尋找的銀彈。堅(jiān)持使用KISS和YAGNI原則。
作為一個(gè)技術(shù)擁護(hù)者和愛好者,你有權(quán)利有自己的喜好。但是當(dāng)面對“正確的選擇”和“喜歡的選擇”的時(shí)候,讓你變得更卓越的是實(shí)用的選擇能力。
祝好運(yùn)。
原文鏈接:https://medium.com/swlh/stop-you-dont-need-microservices-dc732d70b3e0
想要加入中生代架構(gòu)群的小伙伴,請?zhí)砑尤汉匣锶?strong>大白的微信
申請備注(姓名+公司+技術(shù)方向)才能通過哦!
? ?END ? ?? #接力技術(shù),鏈接價(jià)值#精彩推薦1.?從0到1設(shè)計(jì)一個(gè)秒殺系統(tǒng)2.?蘇寧金服技術(shù)大揭秘:支付決策機(jī)器人 3.?阿里P9專家右軍:以終為始的架構(gòu)設(shè)計(jì) 4.?手哥架構(gòu)寶典系列:支付系統(tǒng)2.0架構(gòu)演進(jìn)5.?阿里高級技術(shù)專家王夕寧:Istio網(wǎng)關(guān)之南北向流量管理漫畫推薦1.?漫畫:程序員和產(chǎn)品經(jīng)理撕得真是太太太太厲害了 2.?漫畫:程序員真的是太太太太太太太太難了!3.?漫畫:普通程序員 vs 優(yōu)秀程序員 4.?漫畫:35歲的IT何去何從? 5.?漫畫:從修燈泡來看各種 IT 崗位,你是哪一種? 6. 漫畫:一批90后已經(jīng)30歲了,更扎心的是…7. 圖解:這才是程序員加班的真正原因!8.?漫畫:中國互聯(lián)網(wǎng)往事(2000-2020)總結(jié)
- 上一篇: nyoj359Delete it
- 下一篇: nyoj496巡回赛-拓扑排序-拓扑序列