本文翻譯自Alexandra Noonan 的 Goodbye Microservices: From 100s of problem children to 1 superstar截粗。內(nèi)容是描述 Segment 的架構(gòu)如何從 「單體應(yīng)用」 -> 「微服務(wù)」 -> 「140+ 微服務(wù)」 -> 「單體應(yīng)用」 的一個(gè)歷程。翻譯比較粗糙世曾,如有疏漏治唤,請(qǐng)不吝指教滑凉。
注:下文說(shuō)的目的地就是對(duì)應(yīng)的不同的數(shù)據(jù)平臺(tái)(例如Google Analytics熬拒, Optimizely)
除非你生活在石器時(shí)代矗愧,不然你一定知道「微服務(wù)」是當(dāng)世最流行的架構(gòu)御吞。我們Segment早在2015年就開始實(shí)踐這一架構(gòu)儿子。這讓我們?cè)谝恍┓矫嫔铣粤瞬簧偬痤^瓦哎,但很快我們發(fā)現(xiàn):在其他場(chǎng)景,他時(shí)不時(shí)讓我們吃了苦頭柔逼。
簡(jiǎn)而言之蒋譬,微服務(wù)的主要宣傳點(diǎn)在于:模塊化優(yōu)化,減少測(cè)試負(fù)擔(dān)愉适,更好的功能組成犯助,環(huán)境獨(dú)立,而且開發(fā)團(tuán)隊(duì)是自治的(因?yàn)槊恳粋€(gè)服務(wù)的內(nèi)部邏輯是自洽且獨(dú)立的)维咸。而另一頭的單體應(yīng)用:「巨大無(wú)比且難以測(cè)試剂买,而且服務(wù)只能作為一個(gè)整理來(lái)伸縮(如果你要提高某一個(gè)服務(wù)的性能惠爽,只能把服務(wù)器整體提高)」
2017 早期,我們陷入了僵局瞬哼,復(fù)雜的微服務(wù)樹讓我們的開發(fā)效率驟減婚肆,并且每一個(gè)開發(fā)小組都發(fā)現(xiàn)自己每次實(shí)現(xiàn)都會(huì)陷入巨大的復(fù)雜之中,此時(shí)坐慰,我們的缺陷率也迅速上升较性。
最終,我們不得不用三個(gè)全職工程師來(lái)維護(hù)每一個(gè)微服務(wù)系統(tǒng)的正常運(yùn)行结胀。這次我們意識(shí)到改變必須發(fā)生了赞咙,本文會(huì)講述我們?nèi)绾魏笸艘徊剑寛F(tuán)隊(duì)需要和產(chǎn)品需求完全一致的方法把跨。
為什么微服務(wù)曾經(jīng)可行?
Segment 的客戶數(shù)據(jù)基礎(chǔ)設(shè)施吸收每秒成百上千個(gè)事件沼死,將每一個(gè)伙伴服務(wù)的API 請(qǐng)求結(jié)果一個(gè)個(gè)返回給對(duì)應(yīng)的服務(wù)端的「目的地」着逐。而「目的地」有上百種類別,例如Google Analytics意蛀, Optimizely耸别,或者是一些自定義的webhook。
幾年前县钥,當(dāng)產(chǎn)品初步發(fā)布秀姐,當(dāng)時(shí)架構(gòu)很簡(jiǎn)單。僅僅是一個(gè)接收事件并且轉(zhuǎn)發(fā)的消息隊(duì)列若贮。在這個(gè)情況下省有,事件是由Web或移動(dòng)應(yīng)用程序生成的JSON對(duì)象,例子如下:
{
"type": "identify",
"traits": {
"name": "Alex Noonan",
"email": "anoonan@segment.com",
"company": "Segment",
"title": "Software Engineer"
},
"userId": "97980cfea0067"
}
事件是從隊(duì)列中消耗的谴麦,客戶的設(shè)置會(huì)決定這個(gè)事件將會(huì)發(fā)送到哪個(gè)目的地蠢沿。這個(gè)事件被紛紛發(fā)送到每個(gè)目的地的API,這很有用匾效,開發(fā)人員只需要將他們的事件發(fā)送到一個(gè)特定的目的地——也就是Segment 的API舷蟀,而不是你自己實(shí)現(xiàn)幾十個(gè)項(xiàng)目集成。
如果一個(gè)請(qǐng)求失敗了面哼,有時(shí)候我們會(huì)稍后重試這個(gè)事件野宜。一些失敗的重試是安全的,但有些則不魔策⌒僮樱可重試的錯(cuò)誤可能會(huì)對(duì)事件目的地不造成改變,例如:50x錯(cuò)誤闯袒,速率限制旬牲,請(qǐng)求超時(shí)等仿粹。不可重試的錯(cuò)誤一般是這個(gè)請(qǐng)求我們確定永遠(yuǎn)都不會(huì)被目的地接受的。例如:請(qǐng)求包含無(wú)效的認(rèn)證亦或是缺少必要的字段原茅。
此時(shí)吭历,一個(gè)簡(jiǎn)單的隊(duì)列包含了新的事件請(qǐng)求以及若干個(gè)重試請(qǐng)求,彼此之間事件的目的地縱橫交錯(cuò)擂橘,會(huì)導(dǎo)致的結(jié)果顯而易見(jiàn):隊(duì)頭阻塞晌区。意味著在這個(gè)特定的場(chǎng)景下,如果一個(gè)目的地變慢了或者掛掉了通贞,重試請(qǐng)求將會(huì)充斥這個(gè)隊(duì)列朗若,從而整個(gè)請(qǐng)求隊(duì)列會(huì)被拖慢。
想象下我們有一個(gè) 目的地 X 遇到一個(gè)臨時(shí)問(wèn)題導(dǎo)致每一個(gè)請(qǐng)求都會(huì)超時(shí)昌罩。這不僅會(huì)產(chǎn)生大量尚未到達(dá)目的地 X的請(qǐng)求哭懈,而且每一個(gè)失敗的事件將會(huì)被送往重試的隊(duì)列。即便我們的系統(tǒng)會(huì)根據(jù)負(fù)載進(jìn)行彈性伸縮茎用,但是請(qǐng)求隊(duì)列深度突然間的增長(zhǎng)會(huì)超過(guò)我們伸縮的能力遣总,結(jié)果就是新的時(shí)間推送會(huì)延遲。發(fā)送時(shí)間到每一個(gè)目的地的時(shí)間將會(huì)增加因?yàn)槟康牡豖 有一個(gè)短暫的停止服務(wù)(因?yàn)榕R時(shí)問(wèn)題)轨功⌒癯猓客戶依賴于我們的實(shí)時(shí)性,所以我們無(wú)法承受任何程度上的緩慢古涧。
為了解決這個(gè)隊(duì)頭阻塞問(wèn)題垂券,我們團(tuán)隊(duì)給每一個(gè)目的地都分開實(shí)現(xiàn)了一個(gè)隊(duì)列,這種新架構(gòu)由一個(gè)額外的路由器進(jìn)程組成羡滑,該進(jìn)程接收入站事件并將事件的副本分發(fā)給每個(gè)選定的目標(biāo)」阶Γ現(xiàn)在如果一個(gè)目的地有超時(shí)問(wèn)題,那么也僅僅是這個(gè)隊(duì)列會(huì)進(jìn)入阻塞而不會(huì)影響整體柒昏。這種「微服務(wù)風(fēng)格」的架構(gòu)分離把目的地彼此分開娄帖,當(dāng)一個(gè)目的地老出問(wèn)題,這種設(shè)計(jì)就顯得很關(guān)鍵了昙楚。
個(gè)人Repo 的例子
每一個(gè)目的地的API 的請(qǐng)求格式都不同近速,需要自定義的代碼去轉(zhuǎn)換事件來(lái)匹配格式。一個(gè)簡(jiǎn)單的例子:還是目的地X堪旧,有一個(gè)更新生日的接口削葱,作為請(qǐng)求內(nèi)容的格式字段為 dob ,API 會(huì)對(duì)你要求字段為 birthday淳梦,那么轉(zhuǎn)換代碼就會(huì)如下:
const traits = {}
traits.dob = segmentEvent.birthday
許多現(xiàn)代的目的地終點(diǎn)都用了Segment 的請(qǐng)求格式析砸,所以轉(zhuǎn)換會(huì)很簡(jiǎn)單。但是爆袍,這些轉(zhuǎn)換也可能會(huì)十分復(fù)雜首繁,取決于目的地API 的結(jié)構(gòu)作郭。
起初,目的地分成幾個(gè)拆分的服務(wù)的時(shí)候弦疮,所有的代碼都會(huì)在一個(gè)repo 里夹攒。一個(gè)巨大的挫折點(diǎn)就是一個(gè)測(cè)試的失敗常常會(huì)導(dǎo)致整個(gè)項(xiàng)目測(cè)試無(wú)法跑通。我們可能會(huì)為此付出大量的時(shí)間只是為了讓他像之前一樣正常運(yùn)行通過(guò)測(cè)試胁塞。為了解決這個(gè)問(wèn)題咏尝,我們把每一個(gè)服務(wù)都拆分成一個(gè)單獨(dú)的repo,所有的目的地的測(cè)試錯(cuò)誤都只會(huì)影響自己啸罢,這個(gè)過(guò)渡十分自然编检。
拆分出來(lái)的repo 來(lái)隔離開每一個(gè)目的地會(huì)讓測(cè)試的實(shí)現(xiàn)變得更容易,這種隔離允許開發(fā)團(tuán)隊(duì)快速開發(fā)以及維護(hù)每一個(gè)目的地扰才。
伸縮微服務(wù)和Repo 們
隨著時(shí)間的偏移允懂,我們加了50多個(gè)新的目的地,這意味著有50個(gè)新的repo衩匣。為了減輕開發(fā)和維護(hù)這些codebase 的負(fù)擔(dān)蕾总,我們創(chuàng)建一個(gè)共享的代碼庫(kù)來(lái)做實(shí)現(xiàn)一些通用的轉(zhuǎn)換和功能,例如HTTP 請(qǐng)求的處理舵揭,不同目的地之間代碼實(shí)現(xiàn)更具有一致性谤专。
例如:如果我們要一個(gè)事件中用戶的名字躁锡,event.name() 可以是任何一個(gè)目的地里頭的調(diào)用午绳。共享的類庫(kù)會(huì)去嘗試判斷event 里的 name 或者 Name 屬性,如果沒(méi)有映之,他會(huì)去查 first name拦焚,那么就回去查找first_name 和 FirstName,往下推:last name 也會(huì)做這樣的事情杠输。然后吧first name 和last name 組合成full name.
Identify.prototype.name = function() {
var name = this.proxy('traits.name');
if (typeof name === 'string') {
return trim(name)
}
var firstName = this.firstName();
var lastName = this.lastName();
if (firstName && lastName) {
return trim(firstName + ' ' + lastName)
}
}
共享的代碼庫(kù)讓我們能快速完成新的目的地的實(shí)現(xiàn)赎败,他們之間的相似性帶給我們一致性的實(shí)現(xiàn)而且維護(hù)上也讓我們減少了不少頭疼的地方。
盡管如此蠢甲,一個(gè)新的問(wèn)題開始發(fā)生并蔓延僵刮。共享庫(kù)代碼改變后的測(cè)試和部署會(huì)影響所有的目的地。這開始讓我們需要大量時(shí)間精力來(lái)維護(hù)它鹦牛。修改或者優(yōu)化代碼庫(kù)搞糕,我們得先測(cè)試和部署幾十個(gè)服務(wù),這其中會(huì)帶來(lái)巨大的風(fēng)險(xiǎn)曼追。時(shí)間緊迫的時(shí)候窍仰,工程師只會(huì)在某個(gè)特定的目的地去更新特定版本的共享庫(kù)代碼。
緊接著礼殊,這些共享庫(kù)的版本開始在不同的目標(biāo)代碼庫(kù)中發(fā)生分歧驹吮。微服務(wù)起初帶給我們的種種好處针史,在我們給每一個(gè)目的地都做了定制實(shí)現(xiàn)后開始反轉(zhuǎn)。最終碟狞,所有的微服務(wù)都在使用不同版本的共享庫(kù)——我們本可以用自動(dòng)化地發(fā)布最新的修改啄枕。但在此時(shí),不僅僅是開發(fā)團(tuán)隊(duì)在開發(fā)中受阻篷就,我們還在其他方面遇到了微服務(wù)的弊端射亏。
這額外的問(wèn)題就是每一個(gè)服務(wù)都有一個(gè)明確的負(fù)載模式。一些服務(wù)每天僅處理寥寥幾個(gè)請(qǐng)求竭业,但有的服務(wù)每秒就要處理上千個(gè)請(qǐng)求智润。對(duì)于處理事件較少的目的地,當(dāng)負(fù)載出現(xiàn)意外峰值時(shí)未辆,運(yùn)維必須手動(dòng)伸縮服務(wù)以滿足需求窟绷。(編者注,肯定有解決方案咐柜,但原作者突出的還是復(fù)雜度和成本兼蜈。)
當(dāng)我們實(shí)現(xiàn)了自動(dòng)伸縮的實(shí)現(xiàn),每個(gè)服務(wù)都具有所需CPU和內(nèi)存資源的明顯混合拙友,這讓我們的自動(dòng)伸縮配置與其說(shuō)是科學(xué)的为狸,不如說(shuō)更具有藝術(shù)性(其實(shí)就是蒙的)。
目的地的數(shù)量極速增長(zhǎng)遗契,團(tuán)隊(duì)以每個(gè)月三個(gè)(目的地)的速度增長(zhǎng)著辐棒,這意味著更多的repo,更多的隊(duì)列牍蜂,更多的服務(wù)漾根。我們的微服務(wù)架構(gòu)的運(yùn)維成本也是線性地增長(zhǎng)著。因此鲫竞,我們決定退后一步辐怕,重新考慮整個(gè)流程。
深挖微服務(wù)以及隊(duì)列
這時(shí)列表上第一件事就是如何鞏固當(dāng)前超過(guò)140個(gè)服務(wù)到一個(gè)服務(wù)中从绘,管理所有服務(wù)的帶來(lái)的各種成本成了團(tuán)隊(duì)巨大的技術(shù)債務(wù)寄疏。運(yùn)維工程師幾乎無(wú)眠,因?yàn)殡S時(shí)出現(xiàn)的流量峰值必須讓工程師隨時(shí)上線處理僵井。
盡管如此陕截,當(dāng)時(shí)把項(xiàng)目變成單一服務(wù)的架構(gòu)是一個(gè)巨大的挑戰(zhàn)。要讓每一個(gè)目的地?fù)碛幸粋€(gè)分離的隊(duì)列驹沿,每一個(gè) worker進(jìn)程需要檢查檢查每一隊(duì)列是否運(yùn)行艘策,這種給目的地服務(wù)增加一層復(fù)雜的實(shí)現(xiàn)讓我們感到了不適。這是我們「離心機(jī)」的主要靈感來(lái)源渊季,「離心機(jī)」將替換我們所有的個(gè)體隊(duì)列朋蔫,并負(fù)責(zé)將事件發(fā)送到一個(gè)單體服務(wù)罚渐。
譯者注:「離心機(jī)」其實(shí)就是Segment 制作的一個(gè)事件分發(fā)系統(tǒng)。 相關(guān)地址
image
搬到一個(gè)單體Repo
所以我們開始把所有的目的地代碼合并到了一個(gè)repo驯妄,這意味著所有的依賴和測(cè)試都在一個(gè)單一的repo 里頭了荷并,我們知道我們要面對(duì)的,會(huì)是一團(tuán)糟青扔。
120個(gè)依賴源织,我們都提交了一個(gè)特定的版本讓每一個(gè)目的地都兼容。當(dāng)我們搬完了目的地微猖,我們開始檢查每一個(gè)對(duì)應(yīng)的代碼是否都是用的最新的依賴谈息。我們保證每一個(gè)目的地在最新的依賴版本下,都能正確運(yùn)行凛剥。
這些改變中侠仇,我們?cè)僖膊挥酶櫼蕾嚨陌姹玖恕K心康牡囟际褂猛话姹纠缰椋@顯著地減小了codebase 的代碼復(fù)雜度逻炊。維護(hù)目的地變得快捷而且風(fēng)險(xiǎn)也變小了。
另一方面我們也需要測(cè)試能簡(jiǎn)單快速地運(yùn)行起來(lái)犁享,之前我們得出的結(jié)論之一就是:「不去修改共享庫(kù)文件主要的阻礙就是得把測(cè)試都跑一次余素。」
幸運(yùn)的是炊昆,目的地測(cè)試都有著相似的架構(gòu)桨吊。他們都有基礎(chǔ)的單元測(cè)試來(lái)驗(yàn)證我們的自定義轉(zhuǎn)換邏輯是否正確,而且也能驗(yàn)證HTTP 的返回是否符合我們的期望值窑眯。
回想起我們的出新是分離每一個(gè)目的地的codebase 到各自的repo 并且分離各自測(cè)試的問(wèn)題屏积。盡管如此医窿,現(xiàn)在看來(lái)這個(gè)想法是一個(gè)虛假的優(yōu)勢(shì)磅甩。HTTP 請(qǐng)求的發(fā)送仍然以某種頻率失敗著。因?yàn)槟康牡胤蛛x到各自的repo姥卢,所以大家也沒(méi)有動(dòng)力去處理這類失敗的請(qǐng)求卷要。這也讓我們走進(jìn)了某種令人沮喪的惡性循環(huán)。本應(yīng)只需幾個(gè)小時(shí)的小改動(dòng)常常要花上我們幾天甚至一周的時(shí)間独榴。
構(gòu)建一個(gè)彈性測(cè)試套件
給目的地發(fā)送的HTTP 請(qǐng)求失敗是我們主要的失敗測(cè)試原因僧叉,過(guò)期憑證等無(wú)關(guān)的問(wèn)題不應(yīng)該使測(cè)試失敗。我們從中也發(fā)現(xiàn)一些目的地的請(qǐng)求會(huì)比其他目的地慢不少棺榔。一些目的地的測(cè)試得花上5 分鐘才能跑完瓶堕,我們的測(cè)試套件要花上一小時(shí)時(shí)間才能全部跑完。
為了解決這個(gè)問(wèn)題症歇,我們制作了一個(gè)「Traffic Recorder」郎笆,「Traffic Recorder」是一個(gè)基于yakbak 實(shí)現(xiàn)的工具谭梗,用于記錄并且保存一些請(qǐng)求。無(wú)論何時(shí)一個(gè)測(cè)試在他第一次跑的時(shí)候宛蚓,對(duì)應(yīng)的請(qǐng)求都會(huì)被保存到一個(gè)文件里激捏。后來(lái)的測(cè)試跑的時(shí)候,就會(huì)復(fù)用里頭的返回結(jié)果凄吏。同時(shí)這個(gè)請(qǐng)求結(jié)果也會(huì)進(jìn)入repo远舅,以便在測(cè)試中也是一致的。這樣一來(lái)痕钢,我們的測(cè)試就不再依賴于網(wǎng)絡(luò)HTTP請(qǐng)求图柏,為了接下來(lái)的單一repo 鋪好了路。
記得第一次整合「Traffic Recorder」后任连,我們嘗試跑一個(gè)整體的測(cè)試爆办,完成 140+ 目的地的項(xiàng)目整體測(cè)試只需幾毫秒。這在過(guò)去课梳,一個(gè)目的地的測(cè)試就得花上幾分鐘距辆,這快得像魔術(shù)一般。
為何單體應(yīng)用可行
只要每個(gè)目的地都被整合到一個(gè)repo暮刃,那么他就能作為一個(gè)單一的服務(wù)運(yùn)行跨算。所有目的地都在一個(gè)服務(wù)中,開發(fā)團(tuán)隊(duì)的效率顯著提高椭懊。我們不因?yàn)樾薷牧斯蚕韼?kù)而部署140+ 個(gè)服務(wù)诸蚕,一個(gè)工程師可以一分鐘內(nèi)重新完成部署。
速度是肉眼可見(jiàn)地被提升了氧猬,在我們的微服務(wù)架構(gòu)時(shí)期背犯,我們做了32個(gè)共享庫(kù)的優(yōu)化。再變成單體之后我們做了46個(gè)盅抚,過(guò)去6個(gè)月的優(yōu)化甚至多過(guò)2016年整年漠魏。
這個(gè)改變也讓我們的運(yùn)維工程師大為受益,每一個(gè)目的地都在一個(gè)服務(wù)中妄均,我們可以很好進(jìn)行服務(wù)的伸縮柱锹。巨大的進(jìn)程池也能輕松地吸收峰值流量,所以我們也不用為小的服務(wù)突然出現(xiàn)的流量擔(dān)驚受怕了丰包。
壞處
盡管改變成單體應(yīng)用給我們帶來(lái)巨大的好處禁熏,盡管如此,以下是壞處:
1. 故障隔離很難邑彪,所有東西都在一個(gè)單體應(yīng)用運(yùn)行的時(shí)候瞧毙,如果一個(gè)目的地的bug 導(dǎo)致了服務(wù)的崩潰,那么這個(gè)目的地會(huì)讓所有的其他的目的地一起崩潰(因?yàn)槭且粋€(gè)服務(wù))。我們有全面的自動(dòng)化測(cè)試宙彪,但是測(cè)試只能幫你一部分撑柔。我們現(xiàn)在在研究一種更加魯棒的方法,來(lái)讓一個(gè)服務(wù)的崩潰不會(huì)影響整個(gè)單體應(yīng)用您访。
2. 內(nèi)存緩存的效果變低效了铅忿。之前一個(gè)服務(wù)對(duì)應(yīng)一個(gè)目的地,我們的低流量目的地只有少量的進(jìn)程灵汪,這意味著他的內(nèi)存緩存可以讓很多的數(shù)據(jù)都在熱緩存中√囱担現(xiàn)在緩存都分散給了3000+個(gè)進(jìn)程所以緩存命中率大大降低。最后享言,我們也只能在運(yùn)維優(yōu)化的前提下接受了這一結(jié)果峻凫。
3. 更新共享庫(kù)代碼的版本可能會(huì)讓幾個(gè)目的地崩潰。當(dāng)把項(xiàng)目整合的到一起的時(shí)候览露,我們解決過(guò)之前的依賴問(wèn)題荧琼,這意味著每個(gè)目的地都能用最新版本的共享庫(kù)代碼。但是接下來(lái)的共享庫(kù)代碼更新意味著我們可能還需要修改一些目的地的代碼差牛。在我們看來(lái)這個(gè)還是值得的命锄,因?yàn)樽詣?dòng)化測(cè)試環(huán)節(jié)的優(yōu)化,我們可以更快的發(fā)現(xiàn)新的依賴版本的問(wèn)題偏化。
結(jié)論
我們起初的微服務(wù)架構(gòu)是符合當(dāng)時(shí)的情況的脐恩,也解決了當(dāng)時(shí)的性能問(wèn)題還有目的地之間孤立實(shí)現(xiàn)。盡管如此侦讨,我們沒(méi)有準(zhǔn)備好服務(wù)激增的改變準(zhǔn)備驶冒。當(dāng)需要批量更新時(shí),我們?nèi)狈m當(dāng)?shù)墓ぞ邅?lái)測(cè)試和部署微服務(wù)韵卤。結(jié)果就是骗污,我們的研發(fā)效率因此出現(xiàn)了滑坡。
轉(zhuǎn)向單體結(jié)構(gòu)使我們能夠擺脫運(yùn)維問(wèn)題沈条,同時(shí)顯著提高開發(fā)人員的工作效率需忿。我們并沒(méi)有輕易地進(jìn)行這種轉(zhuǎn)變,直到確信它能夠發(fā)揮作用拍鲤。
1. 我們需要靠譜的測(cè)試套件來(lái)讓所有東西都放到一個(gè)repo贴谎。沒(méi)有它汞扎,我們可能最終還是又把它拆分出去季稳。頻繁的失敗測(cè)試在過(guò)去損害了我們的生產(chǎn)力,我們不希望再次發(fā)生這種情況澈魄。
2. 我們接受一些單體架構(gòu)的固有的壞處而且確保我們能最后得到一個(gè)好的結(jié)果景鼠。我們對(duì)這個(gè)犧牲是感到滿意的。
在單體應(yīng)用和微服務(wù)之間做決定的時(shí)候,有些不同的因素是我們考慮的铛漓。在我們基礎(chǔ)設(shè)施的某些部分溯香,微服務(wù)運(yùn)行得很好。但我們的服務(wù)器端浓恶,這種架構(gòu)也是真實(shí)地傷害了生產(chǎn)力和性能的完美示例玫坛。但到頭來(lái),我們最終的解決方案是單體應(yīng)用包晰。
最后
雖然文章所述的微服務(wù)的問(wèn)題確實(shí)隨著項(xiàng)目的越來(lái)越多帶來(lái)管理和維護(hù)上的麻煩湿镀,但是這不是微服務(wù)的本身問(wèn)題,在拆分業(yè)務(wù)單元時(shí)就需要考慮到伐憾,對(duì)微服務(wù)的體量也要有估計(jì)勉痴。
現(xiàn)在的微服務(wù)的架構(gòu)方面的技術(shù)越來(lái)越多,比如Spring Cloud就可以很好的解決體量帶來(lái)的麻煩和問(wèn)題树肃,所以本人建議微服務(wù)是大有可為的蒸矛。