關(guān)于微服務(wù)的一些深度思考
我知道微服務(wù)這個話題已經(jīng)被討論的太多太多,但我還是想以我在Web應(yīng)用設(shè)計的經(jīng)驗出發(fā),發(fā)表一些我的個人觀點:
很多人認(rèn)為微服務(wù)架構(gòu)解決的是與伸縮性和性能有關(guān)的軟件問題。但其實他們解決的最重要的問題其實是:一個組織的問題。
康威定律永遠(yuǎn)都適用于此。當(dāng)你考慮構(gòu)建的軟件應(yīng)該是什么樣子時,你需要先考慮一下你的組織架構(gòu)應(yīng)該是什么樣子。它們總是相輔相生的。
如果只是一個獨立團(tuán)隊,從這個角度出發(fā),上來就設(shè)計多個可移動組件其實并沒有什么太大意義。誰是每個組件的所有者?某個服務(wù)如何才能真正獨立于其他服務(wù)運行?就因為這樣更方便快捷,然后就做一個類似微服務(wù)架構(gòu)的東西?這其實很容易讓人混淆。
因為他實際上更像是一個“龐大的分布式單體”。從微服務(wù)架構(gòu)起步來設(shè)計應(yīng)用似乎是眾多人的錯誤做法。軟件的架構(gòu)最終往往會和你的組織的架構(gòu)是一樣的。這是必然的。
如果你只有一個團(tuán)隊,千萬不要從微服務(wù)架構(gòu)開始。
隨著組織規(guī)模的擴大,越來越多的人加入到團(tuán)隊中,此時才是真正提出重新審視當(dāng)前架構(gòu)設(shè)計問題的時候。
隨著團(tuán)隊的成長,團(tuán)隊管理會變得越來越困難。將這個龐大的團(tuán)隊拆分成多個、更小、更獨立的團(tuán)隊是團(tuán)隊管理的自然步驟。那么我們需要考慮的問題是:這些團(tuán)隊如何對他們負(fù)責(zé)的產(chǎn)品組件擁有完全的所有權(quán)? 如何讓團(tuán)隊掌握自己的“命運”?
對于一個真正獨立的團(tuán)隊來說,它需要在每一層都有充分的決策權(quán):從UI/UX,到后端將要暴露的API,一直到支撐整個團(tuán)隊的基礎(chǔ)架構(gòu)。作為一個單體應(yīng)用程序這樣做當(dāng)然是可行的,但是這樣團(tuán)隊就需要在他們的開發(fā)過程中進(jìn)行同步,特別是在部署階段。他們經(jīng)常會踩到對方的腳。因此,需要創(chuàng)建一個反映組織架構(gòu)的架構(gòu)。微服務(wù)恰好解決了這個痛點--團(tuán)隊規(guī)模的伸縮。
服務(wù)是需要可組合的,同時需要很好地相互配合,就像你在一個單體中創(chuàng)建可組合的模塊一樣。僅僅是把它拆開,然后再簡單地在它前面配一個Web服務(wù)器并不能拯救你。
對于跨多個領(lǐng)域的特性,必須明確數(shù)據(jù)的所有權(quán),以及清晰一致的API,否則就有可能把所涉及的服務(wù)之間的關(guān)系變得復(fù)雜化。定義這些邊界是開發(fā)此特性的團(tuán)隊的責(zé)任。服務(wù)之間的通信應(yīng)該能反映團(tuán)隊之間的通信。
以下為精彩評論節(jié)選。
acjohnson55:
微服務(wù)不是一個解決方案,它其實反應(yīng)了一種能力。對于團(tuán)隊來說,能夠以輕量的可視化的管道來部署微小的服務(wù)來滿足業(yè)務(wù)需求,這是非常強大的。他們是否應(yīng)該以這種方式打破他們的組織,可能還是需要具體情況具體分析。
在我過往的工作經(jīng)歷中,人們都忽視了微服務(wù)的成本,因為大家都陷入了這是一種去耦合的錯覺。微服務(wù)肯定會使簡單的功能充分包含在服務(wù)中變得更容易,但是一旦一個功能跨越了服務(wù),甚至影響了服務(wù)的契約,你就會陷入比單體架構(gòu)更痛苦的境地。微服務(wù)其實是以犧牲集成的復(fù)雜性為代價來換取局部的簡單性。
微服務(wù),作為一種哲學(xué),在網(wǎng)絡(luò)層編碼你的組織架構(gòu)。我希望你們一開始就能把它分解出來,因為改變它會很痛苦。
我非常支持有那些意義的小型服務(wù)。但就像“所有功能都應(yīng)該是小的”的建議一樣,微服務(wù)已經(jīng)被視為一個設(shè)計原則,而不是一個有爭議的決定。
satyrnein:
在我上家公司,我所在的一個團(tuán)隊選擇重新構(gòu)建一個單體應(yīng)用,最終選擇使用微服務(wù)來“包容”復(fù)雜性。他們構(gòu)建好新的服務(wù),然后用自動化測試來驗證輸入和輸出,他們對此感到非常自豪。隨后來到了集成,很明顯此時的他們忘了考慮如何把數(shù)據(jù)從當(dāng)前的單體應(yīng)用來遷移數(shù)據(jù),如果當(dāng)前的服務(wù)不可用會發(fā)生什么,如何在單體應(yīng)用到微服務(wù)遷移時生成報告,等等。
在這種情況下,使用微服務(wù)就像喝醉了一樣:一種將你所有的問題暫時拋到腦后,只關(guān)注眼前的事情。但你眼前的問題并沒有消失,實際上,只會讓問題變得更糟。
geodel:
確實,我自己做了簡單的計算。假設(shè)我們把一個服務(wù)分成5個微服務(wù)。現(xiàn)在,如果假設(shè)兩個服務(wù)之間有5%的集成相關(guān)問題(顯然這種情況不會在單體應(yīng)用上存在),我們實際上看到的是端到端事務(wù)中會有20%的錯誤幾率。
對我來說,這個比例相當(dāng)高。在我們的場景里,有些報錯還可能是很復(fù)雜的,所以可能會被忽略,從而導(dǎo)致緩慢的數(shù)據(jù)損壞。
amelius:
眾所周知微服務(wù)已經(jīng)經(jīng)過了炒作周期的興奮階段,但并不是說它現(xiàn)在過時了。微服務(wù)架構(gòu)算是我過往印象比較深的項目之一。并且,即使作為行業(yè)的最佳實踐,但也能看到各種各樣失敗的案例。文章是對的,關(guān)于微服務(wù)最棘手的問題實際上是組織問題,而不是技術(shù)問題。
我的看法是,正在考慮采用微服務(wù)的開發(fā)團(tuán)隊?wèi)?yīng)該認(rèn)真考慮他們對組織結(jié)構(gòu)、團(tuán)隊間和部門間溝通的影響程度。如果管理層非常在意發(fā)生在他們自身的各種微小變化,我不會建議給他們提供通過微服務(wù)實現(xiàn)可持續(xù)成功的幾率是多少。也許是其他形式的SOA,但不是真正的微服務(wù)。
bsder:
“微服務(wù),作為一種哲學(xué),在網(wǎng)絡(luò)層編碼你的組織架構(gòu)。”
我其實也并非全盤肯定,但,我非常希望人們能夠把 “微服務(wù)哲學(xué)”采納到以腳本語言為基礎(chǔ)的應(yīng)用當(dāng)中。
例如,如果我想為OpenOffice編寫腳本,我只能用OpenOffice自帶的Python。但,它沒有任何更新;老得不能再老了;還只兼容二進(jìn)制的。這算是極其惱火的限制。
然而,如果他們能提供一個任何人都可以與之交談的“微服務(wù)接口”,而不僅僅是指定的Python,那么你就可以使用一種完全不同的語言運行自己的Python或腳本。
這里的OpenOffice只是個例子,但這并不是針對他們的。
cjfd:
如果一個公司程序員少于100人,你甚至不應(yīng)該考慮微服務(wù)。通常情況下,微服務(wù)被引入不是因為它是否真的有價值,而是因為當(dāng)下流行或被程序員的簡歷描述所引領(lǐng)的。相對來說,我到是都更喜歡重構(gòu)一個糟糕的單體應(yīng)用,而不是重構(gòu)一個糟糕的微服務(wù)。
belter:
整個事情的問題點就是從它們稱為微服務(wù)開始。倒不如就叫它面向服務(wù)的架構(gòu)吧。不要把麻煩都扯到微觀世界上,單體架構(gòu)此時需要些尊重。
cjfd:
面向服務(wù)的架構(gòu)是一個比微服務(wù)更普遍的類別,而且出現(xiàn)的時間要長得多。在許多情況下,它在技術(shù)上更有說服力。舉個例子,你有一個API,它不是世界上最穩(wěn)定的東西,當(dāng)它不正常時,你不希望它把整個應(yīng)用程序都搞垮。
因此,你可以將其放在一個單獨的服務(wù)中,以便于重新啟動。這是分離可執(zhí)行文件的一個很好的技術(shù)原因。當(dāng)人們毫無理由地引入這些區(qū)分時,問題就出現(xiàn)了。這樣就會遇到RPC的所有問題,而沒有任何好處。也就是說,一個人毫無理由地把事情弄得更復(fù)雜。
codyb:
之前有個同事,我們當(dāng)時在一個有4人規(guī)模的創(chuàng)業(yè)公司,那會的他一直提倡微服務(wù)。我們甚至沒有真正懂DevOps的人,連一個真正意義上的VPC用來提供CIDR塊以隔離我們的數(shù)據(jù)庫和公共網(wǎng)絡(luò)也沒有,就這樣,就能搞微服務(wù)?
真不懂這是為了什么!我們連用戶是誰都沒搞定。
然后我們就開始自己測試應(yīng)用的使用體驗,因為除了創(chuàng)始人,我們并沒有實際的用戶,這感覺就像拔牙似的。
這些完全和我的想法背道而馳。
BoorishBears:
對我來說,微服務(wù)不應(yīng)該是一個架構(gòu)。
你可以在一個單體應(yīng)用中擁有可以獨立伸縮的功能模塊,這些功能塊不應(yīng)該是微型的,它們應(yīng)該是有意義的功能模塊,以證明剝離它們的開銷是合理的。
在某種程度上,你的評論反映了這一點,很多地方證明了微服務(wù)的合理性,他們的“微服務(wù)”提供的請求比一般公司的整個代碼庫還要多。
這就是“大數(shù)據(jù)”,有著10GB的日志。
solmag:
我支持你所說的模塊化,消息隊列,異步事件。我個人理解除了最后一個其他都對。
cjfd:
像消息隊列和異步事件這樣的東西對于你喜歡的編程語言來說都是可執(zhí)行的。然后,你可以在具有與機器內(nèi)核相同線程數(shù)的線程池中運行它們。
jayd16:
所以你的意思不僅是單體應(yīng)用,還有單一的實例?僅在進(jìn)程和非共享隊列中?那么,在各個單體之間沒有負(fù)載平衡么?
cjfd:
不一定。我們可以在應(yīng)用程序中使用這些工具,但這并不意味著我們不能將其與某種形式的RPC結(jié)合起來。特別是,是否需要負(fù)載平衡貌似完全是另外一回事。
另一方面,為什么不能用單體應(yīng)用,單體實例?如果一個人使用一種性能語言,想想看,一臺機器上能運行多少。如果他的需求增長,那么就應(yīng)該有一些擴展計劃,這一點是肯定的,但如果不是亂搞,比如在使用某種形式的RCP的應(yīng)用程序之間運行隊列等,那么你可能會驚訝于你的單體應(yīng)用實際上可以做多少事。要知道,搞一套支撐微服務(wù)的配套組件完全不是免費的。
papito:
首先,我們把這些都統(tǒng)稱為“分布式系統(tǒng)”。那些將伸縮作為需求的場景都放到這個系統(tǒng)里。
這個世界最終并沒有“打破摧毀”分布式系統(tǒng)。大多數(shù)公司創(chuàng)建了多個微服務(wù),將他們的小部分研發(fā)放在風(fēng)口浪尖,因為“這就是FAANG的方式”(Facebook,Apple,Amazon,Netflix,Google)。
所有的DRY原則都被拋棄了,現(xiàn)在必須在生產(chǎn)環(huán)境中進(jìn)行調(diào)試——新的術(shù)語是OBSERVABILITY(可觀測性)。
更不用說分布式系統(tǒng)的實際原因是要獨立地擴展系統(tǒng)的多個部分,但是在進(jìn)行擴展之前,你需要知道需要分別擴展哪些部分。當(dāng)然,我看到的是拓?fù)浣Y(jié)構(gòu)確實反映了公司的結(jié)構(gòu)。這不是“需要單獨擴展的東西”,而是“Y團(tuán)隊正在做X,而Y團(tuán)隊不想和Z團(tuán)隊交談,所以他們將創(chuàng)建一個服務(wù),以確保他們不必與人交談”。
人都是自我的。可我們還是得互相交流,而且是大量的交流,因為事情總是不停地出錯,卻沒人知道為什么。
Dropbox、Instagram、StackOverflow——這些公司至今基本上都是單體應(yīng)用。你認(rèn)為你的應(yīng)用需要像谷歌一樣,我覺得這實在有些過于夸張。
所以,我也不會太深入討論一個,能去解決這個大多數(shù)人都沒有遇到的問題,而浪費金錢、人力、CPU和二氧化碳排放。
recursivedoubts:
微服務(wù)的意思就是:獨立部署和擴展的,且小型、單一目的的服務(wù)。在討論微服務(wù)時,我經(jīng)常被康威定律所左右,但團(tuán)隊其實不會以這種方式組織自己。相反,團(tuán)隊在宏觀服務(wù)上工作:給交付團(tuán)隊發(fā)郵件,或監(jiān)督團(tuán)隊,或其他。在大多數(shù)情況下,最好將這些宏服務(wù)作為一個整體來實現(xiàn)和部署,然后通過一個合理的API向外界展示。
throwaway984393:
微服務(wù)之所以被引入,是因為它們似乎能夠很好地解耦和擴展,但它們卻犯了一些錯誤,這讓一切變得更加困難。通常情況下,他們不會計劃如何協(xié)調(diào)他們的工作,這就在設(shè)計中留下了空白,并給業(yè)務(wù)帶來了更多風(fēng)險。
Team?A:
???????↑????????????????????Email?product:
?????__|_____________????????↑??????????Service?C?<----------
????/?How?do?we??????\???????|??????????Service?D?<--????????\
????|?work?together???|????---------------------?????\??------\--------------
????|?on?overall??????|???|?How?do?we?manage????|????|?|?How?do?we???????????|
????|?system?design???|???|?stakeholder?risk????|????|?|?coordinate?changes??|
?????\_______________/?????---------------------?????|?\--------/-----------?/
???????|??????????????????????|??????????????????????|??????????|
???????↓??????????????????????|???????????????????????\?????????|
??Team?B:?????????????????????↓????????????????????????|????????|
????????????????????????????"Data"?team:???????????????|???????/
?????????????????????????????????????????Service?A?<---|-------
?????????????????????????????????????????Service?B?<--/
最重要的是,他們甚至沒有真正的微服務(wù)。它們開始直接調(diào)用彼此的數(shù)據(jù),而不是在API層進(jìn)行接口,它們對彼此的工作方式停留在假設(shè)的層面上,它們不做負(fù)載測試或做限制或配額…… 因為他們都不了解這個系統(tǒng)的其他部分,所以他們不知道他們彼此之間缺乏認(rèn)知其實才是導(dǎo)致他們出問題的原因。
即便是在跨團(tuán)隊合作中,如果他們在一個單體應(yīng)用的項目里,他們其實很有可能在某個偶然的機會中理解到這個系統(tǒng)的其他部分。
bob1029:
從一個單體應(yīng)用開始,只有在你被服務(wù)器硬件瓶頸的驅(qū)使下才會把它分解掉(例如,這個進(jìn)程內(nèi)存不夠或者吃掉了所有的CPU/IO)。一旦你打破了你的單體應(yīng)用,你就失去了它最強大的特性——直接調(diào)用。我看到開發(fā)人員花費在JSON連接協(xié)議、CORS問題、API端點設(shè)計等方面的時間真的開始讓我擔(dān)心了。有時我會想,是否有人想做這種工作,或者這對某些人來說只是個游戲而非實際工作。
我給這個微服務(wù)做了個旅程圖:單體應(yīng)用 => 微服務(wù) => 單體應(yīng)用。
我曾經(jīng)強烈提倡使用微服務(wù),因為它可以很容易地將所有的關(guān)注劃分為每個人可以擁有的快樂的小桶。我們曾經(jīng)把我們的產(chǎn)品賣給我們的客戶,認(rèn)為它有一個“面向微服務(wù)的架構(gòu)”,就好像它能神奇地解決我們所有的問題,或者我們認(rèn)為這才是客戶本應(yīng)該關(guān)注的點。
然而,現(xiàn)實是,所有這一切對我們造成的后果是,我們現(xiàn)有的所有客戶都離開了我們,隨后,我們不得不重新評估在這個市場開展業(yè)務(wù)的愿景。所有有趣/閃亮的技術(shù)對話和想法瞬間蒸發(fā)成現(xiàn)實的烏云。
最終我們使用了單體架構(gòu),我們回到了正軌上。我們再次專注于業(yè)務(wù)和客戶。當(dāng)我們棄用最終的服務(wù)到服務(wù)的JSON API/控制器時,我們感到如釋重負(fù)。不用再檢查一堆不同的日志,也不用再拉出wireshark來弄清楚任意版本的2段不同的代碼之間到底發(fā)生了什么。
jspash:
我馬上就要完成一個項目了這個項目就是把一個面向服務(wù)的系統(tǒng)還原成一個單體應(yīng)用。每一步都減少了代碼行數(shù),修復(fù)了bug,節(jié)省了金錢和時間。我是如此的快樂,同時打算把這個作為我的副業(yè)。要知道,我“拯救”了那些打算被賣掉的,有著復(fù)雜夢想的公司。
bob1029:
最近我經(jīng)常想起這個問題。我認(rèn)為我們正直接面對的是科技領(lǐng)域最大的新興市場之一。我們認(rèn)為,到2025年,TAM (Technology Acceptance Model,技術(shù)接受模型)將如何解決網(wǎng)絡(luò)流量問題?并不是所有的企業(yè)都會因為糟糕的技術(shù)選擇而走向失敗,同時還能支付可觀的咨詢費來為他們解決問題。
我現(xiàn)在已經(jīng)有了一個處理這個問題的流程。它通常從excel的領(lǐng)域建模開始,所有的業(yè)務(wù)相關(guān)人都在同一個討論回環(huán)里,直到每個人都同意為止。我發(fā)現(xiàn)如果你把這部分做對了,那么使用C#還是Python,或者使用AWS還是本地數(shù)據(jù)中心來構(gòu)建實際的產(chǎn)品都沒有什么關(guān)系。當(dāng)你的生產(chǎn)環(huán)境僅僅涉及了一個100MB的ZIP文件和3行Powershell,你很難說到底放在那里更優(yōu)。
wayoutthere:
我還發(fā)現(xiàn)了另一個例子:有關(guān)限制運維爆炸范圍的和部署問題相關(guān)的。我曾經(jīng)與一個大型電信客戶合作,他們的AAA(Authentication,Authorization,Accounting)Web服務(wù)(是的,我們不需要單獨給他們配一套認(rèn)證系統(tǒng),因為這個客戶足夠強大,并且有足夠的專業(yè)知識)作為他們的帳戶管理Web服務(wù),他們將這幾個組件放在了同一個單體中。帳戶管理服務(wù)頻繁地進(jìn)行開發(fā),以支持新功能,而AAA代碼一年只能更新幾次。
如果沒必要,為什么要觸摸每一個產(chǎn)品都依賴的關(guān)鍵Web服務(wù)呢?如果帳戶管理離線,你的業(yè)務(wù)仍在運行,但當(dāng)身份驗證離線時就不一樣了,即使是對認(rèn)證的短暫中斷也是不可接受的(數(shù)以百萬計的客戶),由于服務(wù)的重要性,任何更新都必須在受限的窗口中執(zhí)行。
因此,我們將任務(wù)關(guān)鍵部分分離出來,將它們放在各自的代碼庫中進(jìn)行獨立的版本管理,這讓我們能夠更快地進(jìn)行帳戶管理工作,因為我們可以放心地部署那些并不一定百分百確定的代碼,這歸功于我們不需要等待維護(hù)窗口。
FinanceAnon:
基本上,我覺得單體和微服務(wù)沒什么區(qū)別。
單體應(yīng)用中,可以調(diào)用另一個功能或者類,但在微服務(wù)這些都叫做http調(diào)用。我個人理解服務(wù)的好處是能夠獨立地擴展不同的微服務(wù),能夠為不同的微服務(wù)選擇不同的語言,并且隨著越來越多的人在做它,代碼庫里的沖突也減少了,但你仍然需要處理向后兼容性和終端的版本控制。
當(dāng)你這樣看的時候,我覺得很有趣。微服務(wù)本質(zhì)上是一組作為一個不斷部署的單元函數(shù)。但在Lambdas中,每個函數(shù)都是可以獨立伸縮的單個單元。
trixie_:
http和功能調(diào)用是有本質(zhì)上的區(qū)別的。功能調(diào)用基本上是沒機會出現(xiàn)“無法連接”的錯誤,然而,對于服務(wù)來說,一個服務(wù)無法與另一個服務(wù)通信的原因是無窮無盡的。構(gòu)建一個系統(tǒng)來處理服務(wù)間通信和只調(diào)用同一個二進(jìn)制文件中的函數(shù),這兩點相比,無疑前者是一個巨大的開銷。
bluGill:
我關(guān)注微服務(wù)是出于不同的原因:安全。我已經(jīng)放棄了我們的代碼將永遠(yuǎn)是完全的想法。然而,微服務(wù)意味著,如果有人闖入一個服務(wù),他們無法看到屬于另一個服務(wù)的數(shù)據(jù)。(每個服務(wù)使用不同的用戶運行,因此OS保護(hù)意味著文件命令不能打開這些數(shù)據(jù))。
這只能在非安全代碼相關(guān)的一些威脅起到保護(hù)作用,但保護(hù)層以內(nèi)才是威脅的關(guān)鍵。
choeger:
如果我是一家公司的首席技術(shù)官,微服務(wù)會讓我做噩夢。你如何對使用過的自由軟件(許可證和安全更新)進(jìn)行盡職調(diào)查?如果每個開發(fā)人員都可以添加一個新的自動伸縮服務(wù),你如何規(guī)劃整個資源使用配置?是誰在跟蹤部署以防我們不小心讓系統(tǒng)過載?如何一致地重構(gòu)跨服務(wù)特性?最糟糕的是:誰來跟蹤服務(wù)之間的n*n個合約?
我的意思是,是的,我知道每一個問題都可以解決,有時以一種相對直接的方式。但是,誰真正涵蓋了所有這些方面,那么誰又停掉了僅僅運行幾個月就跑偏了的服務(wù)呢?
roberthahn:
我發(fā)現(xiàn)人們對微服務(wù)的反應(yīng)很有意思。我總是用Unix用戶空間里的工具的相同框架來看待它們——許多小型、集中的應(yīng)用程序做了一些非常好的事情,加上一個超級通用的IPC(Inter-Process Communication,進(jìn)程間通信)機制——在Unix的情況下,使用管道或消息隊列。
但是Unix并不都是小工具。我們有服務(wù)器來處理繁重的工作,比如數(shù)據(jù)庫。
然后挑戰(zhàn)就變成了,你如何設(shè)計IPC機制?也許這個問題其他人也有。但我現(xiàn)在還不知道答案。但這是我經(jīng)常思考的問題,我還沒有看到令人信服的證據(jù)證明“微服務(wù)總是不好的”。
管道對于小型處理任務(wù)非常好,非常有用。“我想知道單詞‘Parameter’在這個代碼庫中的源文件中出現(xiàn)的頻率。”這是偉大的!管道是你的朋友。它們是人類已知的解決這個問題最快的方法。但它們也很脆弱你可能沒有想過這個事實,NoParameter也出現(xiàn)在代碼庫中,你不想再計算它。
現(xiàn)在,當(dāng)寫一些大而復(fù)雜的東西時,管道根本跟不上。沒有人想去瀏覽一個包含著100個通過管道進(jìn)行通信的可執(zhí)行文件。這將是可怕的。你正在尋找的IPC機制,它實際上可以處理瀏覽器所需要的東西,叫做“函數(shù)調(diào)用”,當(dāng)C被引入時,它已經(jīng)非常流行了。
服務(wù)之間的交互機制,例如REST調(diào)用,介于管道和函數(shù)調(diào)用之間。它們比管道可靠一點,但跟函數(shù)調(diào)用相比就不那么可靠了。它們可以用于比管道更復(fù)雜的任務(wù),但不應(yīng)該用于復(fù)雜到需要調(diào)用函數(shù)的任務(wù)。
KronisLV:
“如果你只有一個團(tuán)隊,千萬不要從微服務(wù)架構(gòu)開始。”
這可能是一個很好的觀點,但這并不是故事的全部。
就我個人而言,我同意大多數(shù)團(tuán)隊不應(yīng)該從微服務(wù)開始,單一服務(wù)可以完全足夠,而且單體更容易運行和驗證。否則,最終你可能會面對繁重的運營復(fù)雜度,以至于根本沒有足夠的能力做實際的開發(fā)軟件,并確保它實際上是好的。
但是,你還需要考慮單體應(yīng)用中的耦合,以便在需要時可以輕松地將其分解。實際上,我在我的博客中寫了更多關(guān)于這方面的內(nèi)容,在一篇名為“模塊化:因為我們需要擴展,但我們也負(fù)擔(dān)不起微服務(wù)”的文章中:https://blog.kronis.dev/articles/modulith-because-we-need-to-scale-but-we-also-cannot-afford-micro-services
有一種想法是錯誤的:他們覺得他們的代碼是能工作就不用考慮再多,所以他們生成的PDF報告(PDF Report is a code first reporting engine, PDF Report是一款代碼報告引擎)同整個代碼庫緊密耦合,這與他們的文件上傳和處理邏輯是一樣的。
所以當(dāng)你突然需要前端和后端分離,或提取某個組件,因為它阻止了更新某個新技術(shù)(例如,Java 8到Java 11。一切都可以工作,只有那一個部件不行,所以就得為這一個部件保持舊版本或者不更新版本),然而,單體應(yīng)用的情況下你就不能這么實現(xiàn)。
容器遲早也會出現(xiàn),因為它們可以以一種可管理的方式處理大量應(yīng)用程序,但同時也很容易出錯,這可能是由于不了解技術(shù)或一些潛在的問題引起的。
許多人認(rèn)為“做容器”就是把他們的傳統(tǒng)的單體應(yīng)用放在一個容器中,然后就結(jié)束了。但事實并非如此,如果這樣做,你仍將面臨許多運營挑戰(zhàn)。要“正確地”處理容器,你需要實際了解應(yīng)用程序是如何配置的,如何處理日志記錄、外部服務(wù)以及如何處理持久化數(shù)據(jù)。
這也不是“沒有真正的蘇格蘭人”的謬論(appeal to purity,訴諸純潔,是一種非形式謬誤,是指在原來的普遍宣稱遇到反例時,提出一個理想、純靜的標(biāo)準(zhǔn)以為其辯護(hù)的論證方式。),他們試圖收集一些更有用的可行步驟的建議,例如:https://12factor.net/
盡管這些建議與容器本身沒有直接關(guān)系,但在容器部署之外,它們自己也能很好地工作。
最后,我還看到Kubernetes幾乎被用作容器的同義詞,你不可能在談?wù)撊萜鞯臅r候不提到它。然后,實際上我也看到有些項目失敗了,因為人選擇它是因為它的受歡迎程度,卻無法應(yīng)對它們的復(fù)雜性(“哦,嘿,現(xiàn)在我們還需要Istio Kiali、Helm、哦,還需要一個Nexus去存儲Helm的charts,而且我們還得編寫它們,然后還有一個服務(wù)網(wǎng)格和一些鍵值存儲服務(wù)”),而像Docker Swarm或Hashicorp Nomad這樣的簡單產(chǎn)品就足夠了。
事實上,我還有另一個關(guān)于這個主題的博客主題,“Docker Swarm over Kubernetes”:https://blog.kronis.dev/articles/docker-swarm-over-kubernetes
老實說,這個觀點也適用于容器以外的環(huán)境,例如,選擇像Apache Kafka而不是RabbitMQ這樣的東西,然后被其復(fù)雜性所困。
總而言之,在為任何軟件選擇架構(gòu)時,都得考慮很多因素,同時也要考慮正確使用的技術(shù)。在某些方面,這比僅僅將一些文件推送到運行PHP的FTP服務(wù)器更慢、更麻煩,但從長遠(yuǎn)來看,它也更安全、更高效。遺憾的是,如果一開始就選錯了,那么糟糕的設(shè)計決策將隨著時間的推移而惡化。
maxdo:
這又是一個“基于我的經(jīng)驗”的觀點。根據(jù)我的經(jīng)驗,我們的服務(wù)會因為性能而失敗,因為我們的nodejs仍然是單線程。考慮到這一點,我們要么按照角色重復(fù)部署大型服務(wù),讓你有相同的編排復(fù)雜度,要么用不同的語言重寫,這意味著擁抱微服務(wù)。(PS:我們的產(chǎn)品最初是由非技術(shù)的聯(lián)合創(chuàng)始人編寫的,他們從一開始就使用heroku和微服務(wù)。他們的使用范圍很小,所以一直保持免費的等級。所以在這個用例中,微服務(wù)更便宜。)是的,如果你的后端是一個簡單的服務(wù),那么對于沒有經(jīng)驗的開發(fā)人員來說,跟上它的速度會更簡單。
SomeCallMeTim:
Node可以使用Cluster模塊運行多進(jìn)程。將節(jié)點寫成一個單體,但在100個實例中運行它也是一種選擇。角色可以在軟件中實現(xiàn)。當(dāng)你部署單個服務(wù)時,“編排的復(fù)雜性”要小得多。
因此,單線程Node本身并不是使用微服務(wù)的理由。
我傾向于為服務(wù)的核心API編寫一個整體,然后為需要獨立伸縮的任務(wù)(或者需要在高內(nèi)存/高性能實例上運行)編寫微服務(wù)。所以我并不完全反對使用微服務(wù)。但只有當(dāng)它們對我們有利時,我們才選擇使用它們,而不僅僅是“因為它們已經(jīng)被這樣寫了”。
maxdo:
如果你在不同的角色下部署相同的二進(jìn)制文件,那么復(fù)雜性方面的問題是相同的。
使用現(xiàn)代工具部署和托管存儲根本不是問題,你可以使用模板或構(gòu)建,甚至Lambda與GitLab Github CI功能相結(jié)合。最新的產(chǎn)品能夠讓你無需運維考慮的使用微服務(wù)。在我的團(tuán)隊中,我們沒有專門的運維人員,從開發(fā)人員到產(chǎn)品部的部署都是由開發(fā)人員通過Git運行的。


Redis 實現(xiàn)分布式鎖真的安全嗎?

如何成為一名拖垮團(tuán)隊的程序員?別模仿...

我的前老板絕對是個二貨!
