千萬(wàn)別用微服務(wù)考杉!
本文轉(zhuǎn)載自:眾成翻譯
譯者:賀賀呵呵
鏈接:http://www.zcfy.cc/article/1347
原文:http://basho.com/posts/technical/microservices-please-dont/
關(guān)于譯文,本文英文題目為Microservices - Please Don't影钉,在此我聯(lián)想到多年前的一本書叫做《千萬(wàn)別學(xué)英語(yǔ)》牛郑,其本意是千萬(wàn)別這樣學(xué)英語(yǔ)羔挡,本文的目的亦是如此,因而這里我將題目翻譯為千萬(wàn)別用微服務(wù)伍茄,實(shí)則是想建議讀者栋盹,千萬(wàn)別這樣使用微服務(wù)。在此聲明敷矫,避免誤解~例获。
本文改編自2015年12月份我在波士頓Golang大會(huì)上的一個(gè)簡(jiǎn)短演講汉额。
一時(shí)間,仿佛全世界都在癡迷于討論微服務(wù)(microservice)榨汤。無(wú)數(shù)的新聞?chuàng)涿娑鴣?lái)蠕搜,都在吹捧著訴說(shuō)微服務(wù)模式如何拯救了他們的工程架構(gòu)。你甚至可能曾在這樣的公司工作過(guò)收壕,他們大肆宣傳這種輕量神奇的微小服務(wù)妓灌,并極力宣傳他們是如何使用微服務(wù)解決舊系統(tǒng)的冗余,難以維護(hù)等詬病的蜜宪。
當(dāng)然虫埂,就理想目標(biāo)而言,沒(méi)有什么比現(xiàn)在的技術(shù)更先進(jìn)圃验,更靠譜的了掉伏。理想的美便在于這幾個(gè)月以來(lái),我們始終在為接近完美而不斷地努力著损谦。
我將闡述一些關(guān)于微服務(wù)的主要誤區(qū)和坑點(diǎn)岖免,并借助于一些像上述那樣,將龐大的遺留系統(tǒng)按照微服務(wù)的理念進(jìn)行拆分的企業(yè)作為我的論據(jù)照捡。當(dāng)然,我并不是想用此文來(lái)說(shuō)明微服務(wù)是不好的话侧,而是想通過(guò)我的敘述栗精,能夠讓大家在決定使用這種模式之前提出一些問(wèn)題,多一些思考瞻鹏,再?zèng)Q定是否向這種模式遷移悲立,是否能夠真正的適合你們自己的項(xiàng)目。
到底什么是“微服務(wù)”?
目前真的沒(méi)有對(duì)于微服務(wù)到底由什么組成或者不包含什么的一個(gè)完美的定義新博,但是已經(jīng)有少數(shù)微服務(wù)的支持者薪夕,編撰處理一套比較合理的說(shuō)明。
再?gòu)?qiáng)調(diào)一下赫悄,微服務(wù)不是一個(gè)復(fù)雜的整體原献。在實(shí)踐過(guò)程中,微服務(wù)真正被賦予的意義在于埂淮,其僅僅能夠處理盡可能有限的域空間姑隅,以便其能夠盡可能做最少的事情,在整個(gè)應(yīng)用棧中達(dá)到預(yù)期的服務(wù)目標(biāo)倔撞。舉一個(gè)具體的例子讲仰,如果你有一個(gè)需要“登錄服務(wù)”的銀行,你想要做的最后一步便是獲得用戶的交易記錄痪蝇。你需要將這一需求移交給“交易服務(wù)”一類的進(jìn)行處理(記住鄙陡,命名是一件值得商榷的事情冕房,并不是輕而易舉的)。
此外趁矾,當(dāng)人們討論微服務(wù)的時(shí)候總是在潛意識(shí)里認(rèn)為服務(wù)之間是通過(guò)遠(yuǎn)程交互的耙册。因?yàn)樗鼈兪仟?dú)立的進(jìn)程,而且經(jīng)常運(yùn)行在遠(yuǎn)離其他服務(wù)的地方愈魏,所以使用REST觅玻,或者RPC協(xié)議一類的遠(yuǎn)程協(xié)議進(jìn)行通信變得十分自然。
一開(kāi)始培漏,這看起來(lái)著實(shí)很簡(jiǎn)單溪厘,我們好像只需要把像REST API之類的按照其作用域,封裝成幾個(gè)小的包牌柄,并使這些包之間通過(guò)網(wǎng)絡(luò)進(jìn)行通信畸悬。以我的經(jīng)驗(yàn)來(lái)說(shuō),這里有5條大家所認(rèn)為的“真理”珊佣,在我看來(lái)是有一定問(wèn)題的:
微服務(wù)能夠使代碼簡(jiǎn)潔化
微服務(wù)能夠使對(duì)具有單一目的事物進(jìn)行編碼變得更簡(jiǎn)單
微服務(wù)的使用能讓其比一個(gè)整體系統(tǒng)運(yùn)行的更快
微服務(wù)能夠使得工程師們不用只限于工作在同一個(gè)代碼庫(kù)蹋宦,方便解耦協(xié)作
微服務(wù)使得系統(tǒng)的彈性更容易掌控,通常在這里以使用Docker的方式來(lái)完成
誤區(qū) #1: 更簡(jiǎn)潔的代碼
“你不需要引入一個(gè)網(wǎng)絡(luò)邊界作為借口來(lái)寫更好的代碼”
一個(gè)簡(jiǎn)單的事實(shí)是微服務(wù)咒锻,與其他的建模方法相同冷冗,需要更簡(jiǎn)潔,維護(hù)性更高的代碼惑艇。因?yàn)槲⒎?wù)確實(shí)能夠使得參與工程的部分相對(duì)減少蒿辙,但是這就幾乎等同于說(shuō)你是通過(guò)拋棄一些期望的需求,來(lái)解決你所謂的困難滨巴。你并沒(méi)有真正意義上的攻克難關(guān)思灌,而只是拋棄了許多你可以選擇的需求點(diǎn)。
一個(gè)主流的設(shè)計(jì)微服務(wù)的方式是恭取,圍繞邏輯上擁有獨(dú)立域的“服務(wù)”泰偿,來(lái)設(shè)計(jì)你的內(nèi)構(gòu)件架構(gòu)。這從一方面反映出微服務(wù)可以幫助你確保針對(duì)域開(kāi)發(fā)的獨(dú)立性蜈垮,也有利于幫助你防止從主要業(yè)務(wù)邏輯耗跛,逐漸蔓延到其他地方。另一方面窃款,使用這些微服務(wù)可以避免大量的網(wǎng)絡(luò)使用课兄,以及降低從網(wǎng)絡(luò)中帶來(lái)的潛在風(fēng)險(xiǎn)。
使用微服務(wù)的更大好處是晨继,能夠更好的體現(xiàn)面向服務(wù)架構(gòu)(SOA)的思想烟阐,一旦你決定使用微服務(wù)架構(gòu),那么你事先一定已經(jīng)做了足夠的工作,進(jìn)行了充分的準(zhǔn)備蜒茄,并且對(duì)你所定義的域有了非常到位的理解唉擂,以至于你能夠從中準(zhǔn)確的抽取這個(gè)域。一個(gè)經(jīng)得起推敲的SOA架檀葛,應(yīng)該構(gòu)始于代碼本身玩祟,并且隨著時(shí)間推移,最終能夠落實(shí)到具體應(yīng)用棧的物理拓?fù)浣Y(jié)構(gòu)中去屿聋。
誤區(qū) #2: 微服務(wù)更簡(jiǎn)單
”分布式事務(wù)從來(lái)不會(huì)很容易“
盡管一開(kāi)始覺(jué)得微服務(wù)看上去很簡(jiǎn)單空扎,但是大部分的域(特別是在需要開(kāi)發(fā)原型,制定戰(zhàn)略以及多次重復(fù)定義域本身的一些新興企業(yè))對(duì)于整齊切分業(yè)務(wù)成一個(gè)一個(gè)的小方塊是沒(méi)有什么幫助的润讥。更多的情況是转锈,一個(gè)域想要正確地完成其使命,必須要從借助其他部分獲得數(shù)據(jù)才可以楚殿。特別是當(dāng)其需要委托外部域進(jìn)行寫數(shù)據(jù)任務(wù)時(shí)撮慨,這會(huì)變得尤為復(fù)雜。一旦你打破了一個(gè)域的封閉環(huán)境脆粥,并且需要在外部其他域存儲(chǔ)更改數(shù)據(jù)砌溺,那么你在做的已經(jīng)是分布式事務(wù)了(例如Sagas)。
請(qǐng)求多個(gè)遠(yuǎn)程服務(wù)會(huì)帶來(lái)許多復(fù)雜的問(wèn)題变隔。是并行還是串行處理請(qǐng)求规伐?你是否發(fā)現(xiàn)了所有可能在流程中任何節(jié)點(diǎn)上發(fā)生的潛在風(fēng)險(xiǎn)(在應(yīng)用和網(wǎng)絡(luò)層面上),以及對(duì)這些風(fēng)險(xiǎn)的評(píng)估匣缘?通常情況下楷力,這些分布式事務(wù)有自己的風(fēng)險(xiǎn)異常處理方式,需要做許多努力以確保其不僅僅能發(fā)現(xiàn)異常孵户,并且使其能夠決定如何處理并修復(fù)自身的問(wèn)題。
誤區(qū) #3: 微服務(wù)運(yùn)行更快
“你可以通過(guò)簡(jiǎn)單地應(yīng)用一些額外的法則岔留,使得一個(gè)龐大的系統(tǒng)獲得卓越的性能”
拆分服務(wù)是一件非常困難的事情夏哭,實(shí)際上你經(jīng)常可以通過(guò)減少系統(tǒng)處理事務(wù)的數(shù)量献联,以使得獨(dú)立系統(tǒng)獲得更高的運(yùn)行速度竖配,或者減少獨(dú)立系統(tǒng)加載的依賴等等。
但是從根本上來(lái)說(shuō)里逆,這是種非常逗比的辦法进胯。當(dāng)然我不是質(zhì)疑那些專注于微服務(wù),通過(guò)代碼隔離以加速服務(wù)的人原押,但是你要明白胁镐,這樣做的同時(shí),為了處理大量的調(diào)用,你也帶來(lái)了更多的網(wǎng)絡(luò)開(kāi)銷盯漂。雖然網(wǎng)絡(luò)可以“足夠快”颇玷,但是它也快不過(guò)直接調(diào)用內(nèi)存中的代碼。
此外就缆,許多講述性能優(yōu)化的故事大多是完全以新的語(yǔ)言或技術(shù)棧描述的帖渠,而不只是講述在微服務(wù)中構(gòu)建代碼的一些概念。使用新語(yǔ)言像Scala或Go語(yǔ)言(兩種在微服務(wù)中比較流行的語(yǔ)言)去重構(gòu)一個(gè)用Ruby on Rails或者Django竭宰,甚至是NodeJS寫的應(yīng)用空郊,依賴于技術(shù)選型本身來(lái)提升性能。但是這些語(yǔ)言并不“關(guān)心”你是否將它用來(lái)構(gòu)建“微”服務(wù)進(jìn)程切揭,它們之所以性能更好狞甚,原因很簡(jiǎn)單,因?yàn)樗鼈儽旧淼木幾g環(huán)境等語(yǔ)言特性就很出色伴箩,與你的微服務(wù)其實(shí)并沒(méi)太大關(guān)系入愧。
最后,對(duì)于處在僅需要啟動(dòng)時(shí)使用的應(yīng)用來(lái)說(shuō)嗤谚,CPU棺蛛、內(nèi)存的性能幾乎不成問(wèn)題。問(wèn)題主要出現(xiàn)在I/O上巩步,一個(gè)額外的網(wǎng)絡(luò)調(diào)用只能帶來(lái)更多的I/O負(fù)載旁赊,反而適得其反。
誤區(qū) #4: 方便工程師解耦協(xié)作
“一群軟件工程師維護(hù)一個(gè)獨(dú)立的代碼將可能導(dǎo)致“不是我的問(wèn)題”的詬病”
好像從表面上看這使得使用更小規(guī)模的團(tuán)隊(duì)解決一個(gè)較小規(guī)模的問(wèn)題變得簡(jiǎn)單椅野,但是最終可能總會(huì)帶來(lái)一些其他問(wèn)題终畅,比如解決問(wèn)題的余地變小,使得最終成果物無(wú)法達(dá)到預(yù)期水準(zhǔn)竟闪。
最繁瑣的事情往往是最簡(jiǎn)單的离福,可是一個(gè)微小的改動(dòng)都使得你不得不去運(yùn)行不斷增長(zhǎng)的服務(wù)。這意味著你必須投入時(shí)間精力去為軟件工程師在本地構(gòu)建和維護(hù)一個(gè)能夠簡(jiǎn)單地運(yùn)行所有服務(wù)的系統(tǒng)炼蛤。使用Docker可以方便地實(shí)現(xiàn)妖爷,但是當(dāng)有變動(dòng)發(fā)生時(shí),這仍需要有人維護(hù)理朋。
此外絮识,微服務(wù)使得測(cè)試變得更難,因?yàn)橐鲆淮渭蓽y(cè)試嗽上,需要去了解與之有關(guān)的全部服務(wù)次舌,捕獲全部可能發(fā)生的錯(cuò)誤情況等等。簡(jiǎn)單理解系統(tǒng)就可以花費(fèi)很長(zhǎng)的時(shí)間兽愤,有這時(shí)間還不如去繼續(xù)開(kāi)發(fā)系統(tǒng)彼念。我不是說(shuō)告訴任何工程師挪圾,理解系統(tǒng)是一種浪費(fèi)時(shí)間的表現(xiàn),我只想告誡人們?cè)谀阏嬲枰@些東西之前国拇,不要過(guò)早的引入過(guò)高的復(fù)雜度洛史。
最后,這還會(huì)帶來(lái)一些社會(huì)問(wèn)題酱吝。存在于N多服務(wù)之間的bug也殖,需要多個(gè)團(tuán)隊(duì)殫精竭慮的協(xié)作才能得以修復(fù)。同時(shí)這會(huì)使得團(tuán)隊(duì)缺少責(zé)任感务热,并講責(zé)任推卸給其他團(tuán)隊(duì)忆嗜。而當(dāng)所有人都圍繞著相同的代碼開(kāi)發(fā),他們會(huì)彼此了解崎岂,反而會(huì)使得系統(tǒng)能夠順利發(fā)展捆毫。人們?cè)谝黄鸾鉀Q問(wèn)題時(shí)會(huì)變得更有積極性,相反他們只會(huì)像各個(gè)諸侯國(guó)的國(guó)王一樣死守著自己的一畝三分地冲甘。
誤區(qū) #5: 更好的彈性
“使一整個(gè)龐雜系統(tǒng)變得有彈性的方式绩卤,與使用微服務(wù)一樣簡(jiǎn)單”
不能說(shuō)將你的服務(wù)打包成一個(gè)一個(gè)的獨(dú)立單元,然后使用像Docker這樣的得力工具進(jìn)行水平彈性擴(kuò)展是一件錯(cuò)誤的事情江醇。
但是濒憋,如果說(shuō)只能使用微服務(wù)之類的來(lái)實(shí)現(xiàn)上述情況,那么就大錯(cuò)特錯(cuò)了陶夜。一個(gè)龐雜的整體程序同樣也可以使用上述方法來(lái)創(chuàng)建凛驮。你可以將這個(gè)整體應(yīng)用劃分成許多邏輯簇,每一個(gè)簇僅負(fù)責(zé)整體系統(tǒng)的一個(gè)子集部分条辟。舉例來(lái)說(shuō)黔夭,API請(qǐng)求,你的個(gè)人儀表板羽嫡,以及你的后臺(tái)服務(wù)器本姥,可能都需要共享一個(gè)代碼,但是你不需要在每一個(gè)簇上去處理全部這三個(gè)子集杭棵。
那么優(yōu)點(diǎn)是扣草,就像在微服務(wù)中存在的那樣,你可以按照既定負(fù)載去客制化定義每個(gè)簇的范圍颜屠,并根據(jù)既定負(fù)載對(duì)他們分別進(jìn)行流量調(diào)整。所以在你決定使用微服務(wù)之前鹰祸,你也可以用同樣的方法來(lái)使你的龐雜系統(tǒng)變得有彈性甫窟。
我們什么時(shí)候應(yīng)該使用微服務(wù)?
“當(dāng)你已經(jīng)準(zhǔn)備好組織一個(gè)工程”
我偏向于使用通過(guò)討論什么時(shí)候是采用到這種方法的正確時(shí)間的方式,來(lái)決定是否選用這個(gè)方法蛙婴。(如果你已經(jīng)開(kāi)始使用了這種方法粗井,那么應(yīng)該討論使用這種方法開(kāi)始的方式是否正確)。
創(chuàng)建一個(gè)可靠的,可用的微服務(wù)的一個(gè)非常關(guān)鍵的步驟就是理解“域”的具體內(nèi)容浇衬。如果你不能很好的理解它懒构,或者你還在嘗試去搞懂它,那么這樣的微服務(wù)可能是百害而無(wú)一利的耘擂。但是如果你能夠深入的理解“域”胆剧, 你便可以清晰地描述“域”的邊界是什么,它依賴于什么醉冤,這樣的微服務(wù)才有可能是一個(gè)正確的選擇秩霍。
創(chuàng)建一個(gè)可靠的,可用的微服務(wù)的另一個(gè)關(guān)鍵的步驟是你的工作流蚁阳,特別值得注意的是它們是如何與分布式事務(wù)產(chǎn)生關(guān)聯(lián)的铃绒。如果你了解各種請(qǐng)求在系統(tǒng)中的處理方式,并且知道這些處理方式會(huì)在哪里宕掉螺捐,怎么宕掉的以及它們?yōu)槭裁村吹舻鹊鹊咝憧梢蚤_(kāi)始著手去創(chuàng)建一個(gè)分布式模型,來(lái)處理你的請(qǐng)求定血。
同時(shí)赔癌,理解你的工作流程也是一定程度上在監(jiān)控(monitoring)你的工作流,并且這在某種程度上應(yīng)該成為你工程的核心部分糠悼。你需要精通系統(tǒng)的各個(gè)部分并且需要大量的數(shù)據(jù)來(lái)分析為什么某些部分表現(xiàn)欠佳届榄,甚至是報(bào)錯(cuò)。如果你有一個(gè)靠譜的方法監(jiān)控著整個(gè)系統(tǒng)的各個(gè)部分倔喂,那么當(dāng)你水平擴(kuò)展系統(tǒng)時(shí)铝条,你就可以開(kāi)始理解你的系統(tǒng)行為了。
最后席噩,當(dāng)你能證明項(xiàng)目和業(yè)務(wù)的實(shí)際價(jià)值時(shí)班缰,轉(zhuǎn)移到微服務(wù)將幫助你發(fā)展,壯大悼枢,以及獲得更多的利潤(rùn)埠忘。雖然嘗試新興技術(shù)是件非常有趣的事情,但是許多企業(yè)到頭來(lái)還是受制于成本馒索。如果你因?yàn)橐粋€(gè)說(shuō)“整體且繁雜的系統(tǒng)是不可取的”博客莹妒,不得不推遲發(fā)布一個(gè)可以給企業(yè)帶來(lái)紅利的新功能,那么你就需要通過(guò)某些方式向企業(yè)證明為什么其不可取绰上。有些時(shí)候這種權(quán)衡考慮是值得的旨怠,而有些時(shí)候卻不盡如人意。所以如何抉擇蜈块,選擇正確的技術(shù)路線鉴腻,將在很長(zhǎng)一段時(shí)間使你所在的企業(yè)飛黃騰達(dá)迷扇。
結(jié)論
希望當(dāng)下一次有人建議你使用微服務(wù)架構(gòu)時(shí),你能夠多一些思考爽哎,想一想上述的那一系列條件蜓席。像我開(kāi)頭說(shuō)的那樣,我并不是說(shuō)微服務(wù)是不可取的课锌,相反厨内,如果不從上述的觀點(diǎn)進(jìn)行細(xì)致的權(quán)衡,就跳入微服務(wù)的浪潮中去产镐,難免會(huì)像一個(gè)不會(huì)沖浪的人隘庄,沒(méi)有精湛的技術(shù)與清醒的頭腦迎擊浪潮,最終沉入大海癣亚,以失敗而告終丑掺。
如果你想問(wèn)我應(yīng)該怎樣做,我想說(shuō)述雾,我主張通過(guò)使用簡(jiǎn)潔的代碼定義模塊街州,以及切分獨(dú)立服務(wù)等方式構(gòu)建“內(nèi)部”服務(wù),如果到時(shí)候真正需要這么做的話玻孟。這并不是唯一的方法唆缴,更不是拯救糟糕代碼的靈丹妙藥。但是這將會(huì)使你比在做好準(zhǔn)備之前黍翎,去嘗試處理微服務(wù)做的更好面徽,更快。
Sean Kelly(我們親切地稱其為"Stabby")已經(jīng)從事軟件工程師行業(yè)12年了匣掸。他是Basho公司“Taishi”項(xiàng)目的參與成員趟紊,現(xiàn)在在Komand公司工作,一個(gè)致力于安全服務(wù)編排碰酝,無(wú)需編碼霎匈,授權(quán)給安全團(tuán)隊(duì)迅速進(jìn)行自動(dòng)化構(gòu)建安全環(huán)境的自動(dòng)化平臺(tái)的公司。Komand可以幫助團(tuán)隊(duì)連接他們的工具送爸,構(gòu)建動(dòng)態(tài)工作流铛嘱,優(yōu)化人力,加快事件的響應(yīng)速度袭厂。你可以在twitter上關(guān)注他 @StabbyCutyou