一千個(gè)微服務(wù)之死
沒問(wèn)題制造問(wèn)題
有一則頗為滑稽的場(chǎng)景,講述了一位工程師向項(xiàng)目經(jīng)理解釋一個(gè)過(guò)于復(fù)雜的微服務(wù)系統(tǒng)是如何工作的,以便獲取用戶的生日,但最終仍然解釋不清楚。
圖片
這一場(chǎng)景準(zhǔn)確地描述了當(dāng)前IT文化的荒謬之處。然而在現(xiàn)實(shí)中,如果你跟面試官講了這個(gè)笑話,你猜他會(huì)怎么看你,大概率你不會(huì)通過(guò)面試的。
為什么會(huì)變成這樣呢?我們的目標(biāo)本來(lái)應(yīng)該是讓系統(tǒng)正常的運(yùn)行起來(lái),滿足業(yè)務(wù)的需要,但是現(xiàn)在卻變成了要解決根本沒有的問(wèn)題(微服務(wù)帶來(lái)的問(wèn)題),結(jié)果就是熬了好多個(gè)夜,掉了好多根頭發(fā),給服務(wù)器運(yùn)營(yíng)商分了不少錢,結(jié)果呢?
完美風(fēng)暴
近年來(lái),有幾件事可能導(dǎo)致了當(dāng)前局勢(shì)。
首先,大批使用 JavaScript 前端開發(fā)者開始自稱為“全?!?,涉足服務(wù)器開發(fā)和異步代碼,比如node,比如 Vercel 對(duì) React 的魔幻操作。JavaScript就是JavaScript,使用它創(chuàng)建什么不重要, 用戶界面、服務(wù)器、游戲還是嵌入式系統(tǒng)。對(duì)吧?
Node當(dāng)時(shí)還只是一個(gè)人的學(xué)習(xí)項(xiàng)目,早期的JavaScript是服務(wù)器開發(fā)盡量要避免的,或者不可能選擇的語(yǔ)言。但你如果和一些固執(zhí)的 JavaScript、Node開發(fā)者來(lái)說(shuō),會(huì)遭到對(duì)方的鄙夷。畢竟,這是他們知道的全部,Node之外的世界實(shí)際上是不存在,Node就是唯一的選項(xiàng),因此這是我們至今要處理的固執(zhí)、教條主義思維的起源。
另外,還有一大批大廠向外輸送的“人才”涌入初創(chuàng)公司或者小公司隊(duì)伍中。用大廠的那一套模式和方法來(lái)指導(dǎo)團(tuán)隊(duì),即使這套模式并不合適。那不是他要考慮的?!拔也还埽趺礇]有單獨(dú)的用戶服務(wù)呢?將來(lái)怎么擴(kuò)展呢,兄弟!”
還有一個(gè)不得不說(shuō)的事實(shí),在國(guó)內(nèi)凡是面試,必定要問(wèn)微服務(wù),從來(lái)也不看看線上用戶才多少,開發(fā)團(tuán)隊(duì)才幾個(gè)人。這就導(dǎo)致很多沒有接觸過(guò)微服務(wù)的開發(fā)者,愿意在平時(shí)的項(xiàng)目中嘗試微服務(wù),因?yàn)槟軌蚍e累一些經(jīng)驗(yàn),方面以后跳槽能拿到更多的錢。
在早些時(shí)候,分布式系統(tǒng)是受到尊重、畏懼和普遍盡量避免的,僅作為處理特別棘手問(wèn)題的最后手段。一旦涉及分布式系統(tǒng),就會(huì)變得更具挑戰(zhàn)性、更加耗時(shí),無(wú)論是開發(fā)、調(diào)試、部署、測(cè)試。
但是現(xiàn)在卻變得超級(jí)容易了,因?yàn)橛辛烁鞣N各樣的框架和工具,比如docker、k8s,以及像 Spring Cloud、Dubbo 等各式各樣拿來(lái)即用的框架。
這里的摘要讓我印象深刻,因?yàn)樗錆M了常識(shí)性的結(jié)論:有一份關(guān)于5年初創(chuàng)公司審計(jì)摘要:那些表現(xiàn)最好的初創(chuàng)公司,通常對(duì)工程學(xué)采取了一種竭盡所能“保持簡(jiǎn)單”的方法。純粹為了耍聰明是被鄙視的。相反,那些讓我們感到“哇,這些人真是聰明極了”的公司,大部分都已經(jīng)消失了。
許多初創(chuàng)公司遇到了一種“冒牌綜合癥”的問(wèn)題。在構(gòu)建直截了當(dāng)、簡(jiǎn)單、高性能系統(tǒng)時(shí),那些一開始沒有使用微服務(wù)的公司,常常會(huì)疑惑“只要一個(gè)Spring Boot單體維護(hù)就可以,由幾個(gè)工程師維護(hù),還有一個(gè)MySQL實(shí)例,難道系統(tǒng)不應(yīng)該這么做嗎?”。答案是“沒有”。
同樣,有經(jīng)驗(yàn)的開發(fā)者在當(dāng)今 IT 環(huán)境中常常會(huì)陷入自我懷疑和自我否定。好消息是,這可能不是你的問(wèn)題。
在今天的技術(shù)世界中,一些團(tuán)隊(duì)或開發(fā)者往往假裝他們?cè)谧龈卟l(fā)、超復(fù)雜的系統(tǒng),但他們可能甚至不知道數(shù)據(jù)庫(kù)索引的基礎(chǔ)知識(shí)。我們正處在一個(gè)充滿不合理的過(guò)度自信、浪費(fèi)的海洋中,那么真正的騙子是誰(shuí)呢?
單體架構(gòu)沒有錯(cuò)
如果你沒有一個(gè)看起來(lái)像臭名昭著的阿富汗戰(zhàn)爭(zhēng)戰(zhàn)略圖式的系統(tǒng)架構(gòu)圖,你就無(wú)法成長(zhǎng),這種想法是一個(gè)笑話。
圖片
Dropbox、Twitter、Netflix、Facebook、GitHub、Instagram、Shopify、StackOverflow ,這些公司和其他公司都以單一代碼庫(kù)開始。其中許多公司的核心仍然是單體。StackOverflow引以為傲的是他們運(yùn)行龐大網(wǎng)站所需的硬件非常少。Shopify仍然是一個(gè)Rails單體,利用了經(jīng)過(guò)驗(yàn)證的Resque來(lái)處理數(shù)十億個(gè)任務(wù)。
WhatsApp是以Erlang單體和一個(gè)相對(duì)較小的團(tuán)隊(duì)開發(fā)而最終成功的。并一直將團(tuán)隊(duì)人員保持在較小規(guī)模,只有大約50名工程師。每個(gè)Team也很小,由1-3名工程師組成,每個(gè)Team都擁有很大的自主權(quán)。
在服務(wù)器方面,WhatsApp更傾向于使用較少數(shù)量的服務(wù)器,并將每臺(tái)服務(wù)器縱向擴(kuò)展到最大程度。縱向擴(kuò)展就是加強(qiáng)單機(jī)配置,比如增加 CPU、內(nèi)存、存儲(chǔ)等,相對(duì)而言,增加多臺(tái)服務(wù)器叫做橫向擴(kuò)展。
Instagram被以數(shù)十億美元收購(gòu) ,團(tuán)隊(duì)只有12個(gè)人。
不要解決您沒有的問(wèn)題
這是一個(gè)簡(jiǎn)單的問(wèn)題,您解決的是什么問(wèn)題?是規(guī)模問(wèn)題嗎?
當(dāng)你準(zhǔn)備將系統(tǒng)做成復(fù)雜的微服務(wù)架構(gòu)時(shí),你就要面對(duì)下面眾多的問(wèn)題:
- 系統(tǒng)的拆分策略是什么,哪些功能要?dú)w結(jié)為一個(gè)服務(wù),哪些要隔離開;
- 分布式系統(tǒng)是為高并發(fā)、穩(wěn)定性而建立的。您的系統(tǒng)是否可以同時(shí)擴(kuò)展性和穩(wěn)定性?
- 如果其中一個(gè)服務(wù)崩潰或變慢會(huì)發(fā)生什么?會(huì)影響到其他服務(wù)嗎?
- 你是否考慮了如果將會(huì)發(fā)生了變化,將如何應(yīng)對(duì)?
- 要做壓力測(cè)試,要有斷容器,有隊(duì)列,分布式事務(wù)等等。
- 每個(gè)接口都有合理的超時(shí)時(shí)間嗎?
- 有沒有絕對(duì)安全的保護(hù)措施,以確保簡(jiǎn)單的變更不會(huì)導(dǎo)致整個(gè)系統(tǒng)崩潰?
這是,需要了解和調(diào)整的配置和功能就是無(wú)窮無(wú)盡的,這樣,我們?cè)诮鉀Q業(yè)務(wù)問(wèn)題的同時(shí),又增加許多本來(lái)不必要的問(wèn)題,甚至這些不必要的問(wèn)題超過(guò)了原本的業(yè)務(wù)問(wèn)題。
事實(shí)上,大多數(shù)公司永遠(yuǎn)不會(huì)達(dá)到真正需要構(gòu)建真正分布式系統(tǒng)的規(guī)模,這實(shí)際上可能只是在浪費(fèi)金錢和時(shí)間。
比分布式系統(tǒng)更糟糕的是錯(cuò)誤的分布式系統(tǒng)。
拆成微服務(wù),每個(gè)團(tuán)隊(duì)都只維護(hù)自己的 API?
將問(wèn)題分解為更小的部分,然后逐個(gè)解決,是一種常見方法。那么,是不是你將一個(gè)服務(wù)分解為多個(gè)服務(wù),一切都會(huì)變得更容易呢?
這個(gè)說(shuō)法是充滿理想主義的,每個(gè)微服務(wù)都由一個(gè)專門的團(tuán)隊(duì)維護(hù),圍繞著一個(gè)漂亮的、向后兼容的、有版本的API。從此之后,你就很少甚至不必與這個(gè)團(tuán)隊(duì)溝通了, 就好像這個(gè)微服務(wù)是由一個(gè)第三方供應(yīng)商維護(hù)的一樣。
但事實(shí)往往是事與愿違的。事實(shí)上,公司各種群聊中充斥著來(lái)自團(tuán)隊(duì)的消息,這些消息涉及發(fā)布、錯(cuò)誤、配置更新、破壞性更改等等。每個(gè)人都需要隨時(shí)了解所有的內(nèi)容,甚至比之前更多的內(nèi)容。
多個(gè)微服務(wù)如何維護(hù)
構(gòu)建微服務(wù)有很多陷阱,要么完全沒有得到充分認(rèn)識(shí),要么被簡(jiǎn)單地忽視了。
很有可能是,團(tuán)隊(duì)花費(fèi)很長(zhǎng)時(shí)間編寫高度定制的工具,并且得到了跟核心產(chǎn)品毫不相關(guān)的教訓(xùn)。這里只是一些經(jīng)常被忽視的方面:
每個(gè)服務(wù)往往都充滿了冗余的樣板文件,樣板代碼。很多時(shí)候,這種樣板的開銷很大,而為了保持微服務(wù)的“微小”,這些冗余、通用的部分會(huì)被抽離出去,那么,這些抽離出去代碼怎么維護(hù)呢?
弄一個(gè)通用庫(kù)嗎?如何更新通用庫(kù)呢?還是到處保留不同的版本?又或者定期強(qiáng)制更新呢?還是允許每一個(gè)微服務(wù)有重復(fù)呢?
到最后就變成了,去你的,還是按照自己習(xí)慣的方式重新發(fā)明輪子吧。
在單體架構(gòu)中,更新和打補(bǔ)丁很容易,因?yàn)橐磺卸荚谝黄稹T谖⒎?wù)中,打個(gè)補(bǔ)丁可能意味著在整個(gè)復(fù)雜系統(tǒng)中蜂群一般的更改。如果有十個(gè)微服務(wù)依賴于同一項(xiàng)更改,怎么確定是哪十個(gè)微服務(wù)依賴了更改?如果不知道,那么這些更改如何處理?或者更糟糕的是,如果一個(gè)團(tuán)隊(duì)拒絕進(jìn)行更改怎么辦?那可能會(huì)在重新啟動(dòng)微服務(wù)時(shí)發(fā)現(xiàn)一個(gè)甚至多個(gè)詭異的問(wèn)題。
返璞歸真
最近,有不少的企業(yè),還是比較大的企業(yè)將一些原本是微服務(wù)架構(gòu)的系統(tǒng)回歸到了單體架構(gòu)。
亞馬遜的 Prime Video 團(tuán)隊(duì)將微服務(wù)架構(gòu)遷移到了單體,云成本降低了 90%。
圖片
在Uber,正在將許多微服務(wù)遷移到所謂的 "寬松服務(wù)"(well-sized services)。確實(shí),測(cè)試和維護(hù)數(shù)千個(gè)微服務(wù)不僅很困難,而且長(zhǎng)期來(lái)看可能會(huì)比解決短期問(wèn)題帶來(lái)更多麻煩。
圖片
打個(gè)比喻,要從北京到上海,是建造一艘復(fù)雜的宇宙飛船呢,還是買一張高鐵票來(lái)的實(shí)在?
英文原文地址:https://renegadeotter.com/2023/09/10/death-by-a-thousand-microservices.html