<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          我曾目睹的微服務(wù)災(zāi)難

          共 4270字,需瀏覽 9分鐘

           ·

          2021-07-04 22:25

          作者 | Jo?o Alves
          策劃 | 田曉旭
          2014 年 Martin Fowler 發(fā)表了一篇關(guān)于微服務(wù)的文章,當(dāng)時(shí),我所在的團(tuán)隊(duì)正在構(gòu)建面向服務(wù)的架構(gòu)。這篇文章以及隨后的炒作幾乎影響了世界上所有的軟件團(tuán)隊(duì)。那時(shí),“Netflix OSS ?!笔鞘澜缟献羁岬臇|西,它可以讓世界各地的工程師在分布式系統(tǒng)中使用 Netflix 的經(jīng)驗(yàn)。六年多過去了,如果我們現(xiàn)在來看看軟件工程的工作,就會(huì)發(fā)現(xiàn),其中大部分都是關(guān)于微服務(wù)的架構(gòu)的。
          1炒作驅(qū)動(dòng)開發(fā)

          在 2010 年代的早期,很多組織都面臨著軟件開發(fā)周期的挑戰(zhàn)。與其他 50、100 或 200 名工程師一起工作的人,他們在開發(fā)環(huán)境、QA 過程和程序部署方面都很困難。Martin Fowler 的《Continuous Delivery》(譯注:尚無中譯本)一書給許多團(tuán)隊(duì)帶來了曙光,他們開始意識到,他們那“雄偉”的單體應(yīng)用正給他們帶來組織問題。所以,微服務(wù)對軟件工程師很有吸引力。在一個(gè)大項(xiàng)目中引入持續(xù)交付或部署,而不是一開始就引入,更具有挑戰(zhàn)性。

          于是,團(tuán)隊(duì)開始拆分三個(gè)、十個(gè)、一百個(gè)微服務(wù)。其中大部分都使用“JSON over HTTP”(其他人可能會(huì)稱之為 RESTful)API 來在這些組件之間實(shí)現(xiàn)遠(yuǎn)程調(diào)用。人們對 HTTP 協(xié)議非常熟悉,這看起來是一種將單體應(yīng)用轉(zhuǎn)換成小程序塊的簡單方法。這時(shí),團(tuán)隊(duì)在 15 分鐘之內(nèi)就開始將代碼部署到生產(chǎn)環(huán)境中。再也沒有“哦,團(tuán)隊(duì) A 破壞了 CI 管道,我不能部署我的代碼”這樣的情況了,這種感覺棒極了!

          但是,大多數(shù)工程師都忘了,在解決軟件架構(gòu)層面的組織問題的同時(shí),他們也引入了許多復(fù)雜性。分布式系統(tǒng)的謬誤變得越來越明顯,并很快讓這些團(tuán)隊(duì)感到頭疼。甚至那些已經(jīng)在做客戶機(jī) / 服務(wù)器架構(gòu)的公司,當(dāng)他們的系統(tǒng)中有超過 10 個(gè)移動(dòng)部分時(shí),也會(huì)出現(xiàn)這種情況。

          2現(xiàn)實(shí)的反擊

          做出重大的架構(gòu)改變并非沒有成本。團(tuán)隊(duì)開始認(rèn)識到,共享數(shù)據(jù)庫是一種單點(diǎn)故障。后來他們意識到,他們各自的領(lǐng)域創(chuàng)造了一個(gè)全新的世界:最終的一致性就是一件事。在你提取數(shù)據(jù)的服務(wù)失敗后該怎么辦?很多問題開始堆積如山。高速開發(fā)速度的承諾被尋找錯(cuò)誤、事件和數(shù)據(jù)一致性問題等壓得喘不過氣。另外一個(gè)問題是,工程師需要一種集中的日志和可觀察性解決方案,在幾十個(gè)服務(wù)中發(fā)現(xiàn)并糾正這些缺陷。

          3災(zāi)難 1:服務(wù)規(guī)模過小

          隨著開發(fā)人員創(chuàng)造力的爆發(fā),每天都能創(chuàng)造出新的服務(wù)。一項(xiàng)新功能?咣當(dāng),讓我們開始服務(wù)吧!突然之間,20 名工程師組成了維護(hù) 50 項(xiàng)服務(wù)的小組。一人負(fù)責(zé)一項(xiàng)服務(wù)還不夠!一般而言,代碼的問題在于它會(huì)“腐爛”。維護(hù)每一項(xiàng)服務(wù)都是要付出代價(jià)的。想象一下,在你的服務(wù)團(tuán)隊(duì)中傳播一個(gè)庫的升級。再想象一下,這些服務(wù)開始于不同的時(shí)間點(diǎn),具有不同的架構(gòu)、業(yè)務(wù)邏輯和所使用的框架之間的糾葛。那是多么可怕??!解決這些問題的方法當(dāng)然是有的。其中大部分都不能使用,而其他一些則需要花費(fèi)很多 FTE 工作。

          另外一種感覺是,我被告知,在服務(wù) A 中部署新功能,并且在服務(wù) B 中同時(shí)部署,或者當(dāng)人們開始編寫服務(wù)以生成 CSV 時(shí)。為什么會(huì)有人引入網(wǎng)絡(luò)跳轉(zhuǎn),以產(chǎn)生世界上已知的文件格式?這東西誰來維護(hù)?有些團(tuán)隊(duì)正在受服務(wù)之苦。更糟的是,它在開發(fā)過程中會(huì)產(chǎn)生許多摩擦。與僅僅在 IDE 中查看一個(gè)項(xiàng)目不同,人們需要一次打開多個(gè)項(xiàng)目才能了解所有這些混亂的情況。

          4災(zāi)難 2:開發(fā)環(huán)境

          我已經(jīng)記不清有多少次有人走近我說:

          “嘿,Jo?o。你有時(shí)間嗎?我們需要改善開發(fā)環(huán)境了!大家都在抱怨這些事,可是都沒用!”

          這一問題涉及各個(gè)層面。移動(dòng)開發(fā)者不需要在開發(fā)環(huán)境中開發(fā)功能就可以實(shí)現(xiàn),或者后端開發(fā)者想要嘗試他們的服務(wù)而不會(huì)破壞任何業(yè)務(wù)流程。如果有人想在生產(chǎn)之前在移動(dòng)應(yīng)用中測試整個(gè)過程,這也是一個(gè)問題。

          跨分布式系統(tǒng)的開發(fā)環(huán)境存在一些問題,尤其是規(guī)模方面:

          1. 在云供應(yīng)商中啟動(dòng) 200 個(gè)服務(wù)需要花費(fèi)多少錢?你能做到嗎?你是否能夠啟動(dòng)運(yùn)行他們所需的基礎(chǔ)設(shè)施呢?

          2. 這需要多長時(shí)間呢?加入一個(gè)移動(dòng)工程師開始開發(fā)一項(xiàng)功能,在給定的版本中有一組服務(wù),當(dāng)這些服務(wù)完成之后,有 10 個(gè)新版本被部署到生產(chǎn)中,那會(huì)怎樣?

          3. 測試數(shù)據(jù)怎么樣?你是否擁有所有服務(wù)的測試數(shù)據(jù)?在整個(gè) Fleet 中都保持一致,所以用戶和其他實(shí)體相匹配?

          4. 當(dāng)你開發(fā)一個(gè)多租戶、多區(qū)域的應(yīng)用時(shí),如何配置和功能標(biāo)志?怎樣跟上生產(chǎn)進(jìn)度?若同時(shí)更改缺省值呢?

          這些只是冰山一角而已。你可能會(huì)考慮將工程技術(shù)應(yīng)用于這個(gè)問題。那也許行得通。但是,我懷疑大多數(shù)組織是否有足夠大的規(guī)模來完成這項(xiàng)工作。這樣做既麻煩又費(fèi)錢。

          5災(zāi)難 3:端到端測試

          不難想象,端到端測試和開發(fā)環(huán)境有相似的問題。在此之前,使用虛擬機(jī)或容器創(chuàng)建新的開發(fā)環(huán)境相對簡單。同樣,使用 Selenium 創(chuàng)建測試套件非常簡單,它可以在部署新版本之前通過業(yè)務(wù)流并判斷它們是否在工作。有了微服務(wù),即使我們能夠解決以上關(guān)于構(gòu)建環(huán)境的所有問題,我們也不能再次宣布系統(tǒng)正在運(yùn)行。我們至多可以這樣說,運(yùn)行特定版本的服務(wù)和特定配置的系統(tǒng)可以在特定的時(shí)間點(diǎn)上正常工作。真是大不相同??!

          要讓人們相信我們只能進(jìn)行幾次這樣的測試是非常困難的。而且在持續(xù)集成(Continuous Integration)流程中運(yùn)行這些測試并不夠。它們應(yīng)該持續(xù)運(yùn)行。它們應(yīng)該針對生產(chǎn)運(yùn)行情況發(fā)出相應(yīng)的警報(bào)。我已經(jīng)分享了無數(shù)次 Cindy Sridharan 的文章《在生產(chǎn)中測試,安全的方法》(Testing in production, the safe way),試圖讓人們理解我的觀點(diǎn)。

          6災(zāi)難 4:巨大的共享數(shù)據(jù)庫

          一種簡單的方法就是繼續(xù)使用共享數(shù)據(jù)庫,這樣就可以避免單體應(yīng)用,同時(shí)保證數(shù)據(jù)的一致性。這種方法不會(huì)增加操作負(fù)荷,而且可以輕松地一步一步地切割單體應(yīng)用。但它也有相當(dāng)大的缺點(diǎn)。這不僅是一個(gè)明顯的單點(diǎn)故障,而且違背了面向服務(wù)架構(gòu)的一些原則。你是否為每項(xiàng)服務(wù)創(chuàng)建一個(gè)用戶?你是否具有細(xì)粒度的權(quán)限,以便服務(wù) A 只能讀寫特定的表?假如某人不小心刪除了索引怎么辦?怎樣知道有多少服務(wù)使用了不同的表?那擴(kuò)容呢?

          解決這些問題本身就變成了一個(gè)全新的難題。在技術(shù)上,這可能不是一個(gè)無關(guān)緊要的小問題,因?yàn)閿?shù)據(jù)庫經(jīng)常比軟件壽命長。用數(shù)據(jù)復(fù)制來解決問題——不管是 Kafaka、AWS DMS 還是其他什么——都需要你的工程團(tuán)隊(duì)理解數(shù)據(jù)庫的細(xì)節(jié),以及如何處理重復(fù)時(shí)間等等。

          7災(zāi)難 5:API 網(wǎng)關(guān)

          在面向服務(wù)的架構(gòu)中,API 網(wǎng)關(guān)是一種典型模式。它們幫助解耦后端與前端消費(fèi)者。在實(shí)施端點(diǎn)聚合、速率限制或跨系統(tǒng)認(rèn)證方面,它們也有用。近來,業(yè)界傾向于 backend-for-frontend(BFF,服務(wù)于前端的后端)的架構(gòu),將網(wǎng)關(guān)部署到前端的每個(gè)消費(fèi)者群體(iOS、Android、Web 或桌面應(yīng)用),從而解耦它們的進(jìn)化。

          和世界上的任何東西一樣,人們開始有了新的創(chuàng)造性用例。有時(shí)這只是一個(gè)小技巧,使移動(dòng)應(yīng)用能夠向后兼容。突然間,你的 API 網(wǎng)關(guān)變成了一個(gè)單點(diǎn)故障,因?yàn)槿藗儼l(fā)現(xiàn)在一個(gè)地方進(jìn)行認(rèn)證更加容易,其中還包含一些出乎意料的業(yè)務(wù)邏輯?,F(xiàn)在,你不再有一個(gè)獲得所有流量的單體應(yīng)用,而是有一個(gè)自己開發(fā)的 Spring Boot 服務(wù)來或許所有的流量!會(huì)出什么問題呢?工程人員很快意識到這是個(gè)錯(cuò)誤,但是由于存在大量的定制,有時(shí)候他們不能用它來取代無狀態(tài)的、可擴(kuò)展的定制。

          當(dāng)使用未分頁的端點(diǎn)或返回大量響應(yīng)時(shí),就會(huì)導(dǎo)致 API 網(wǎng)關(guān)災(zāi)難。又或者,如果你在沒有后備機(jī)制的情況下進(jìn)行聚合,僅僅調(diào)用一次 API 就會(huì)“燒毀”你的網(wǎng)關(guān)。

          8災(zāi)難 6:超時(shí)、重試和彈性

          分布式系統(tǒng)經(jīng)常處于局部故障模式。如果服務(wù) A 不能與服務(wù) B 取得聯(lián)系,會(huì)發(fā)生什么?咱們可以再試一次,對嗎?但是這很快讓我們陷入了困惑之中。我見過有些團(tuán)隊(duì)使用斷路器,然后對下游服務(wù)進(jìn)行 HTTP 調(diào)用時(shí)會(huì)超時(shí)。盡管這可能是一種正常的反應(yīng),為我們爭取了一些時(shí)間來解決問題,但是它會(huì)產(chǎn)生二階效應(yīng)。所有這些請求都將被斷路器取消,因?yàn)樗鼈兲L,在斷路器上的時(shí)間太長。隨著流量的增加,會(huì)有越來越多的請求進(jìn)入隊(duì)列,結(jié)果會(huì)比你希望修復(fù)的更糟。工程師們都在努力理解隊(duì)列理論,理解為什么會(huì)出現(xiàn)超時(shí)現(xiàn)象。同樣的事情發(fā)生在團(tuán)隊(duì)開始討論 HTTP 客戶端的線程池等問題時(shí)。盡管對這些東西進(jìn)行配置本身就是一種藝術(shù),但基于直覺來設(shè)置數(shù)值會(huì)使你陷入嚴(yán)重的停機(jī)狀態(tài)。

          在從失敗中恢復(fù)的過程中,一個(gè)棘手的問題是并非所有的失敗都一樣。有些情況下,我們會(huì)希望我們的消費(fèi)者是等冪的。但是這意味著我們應(yīng)該積極的決定每一種失敗情況下該怎么做。消費(fèi)者是否等冪?能否重試這個(gè)調(diào)用?在認(rèn)識到存在巨大的數(shù)據(jù)完整性問題之前,我已經(jīng)看到許多工程師忽視了這些,因?yàn)樗鼈冎皇恰斑吘壡闆r”。

          即使你設(shè)置了后備機(jī)制,重試也比所有這些更加復(fù)雜。假設(shè)你的移動(dòng)應(yīng)用有 500 萬用戶,而更新用戶首選項(xiàng)的消息總線暫時(shí)無法運(yùn)行。你創(chuàng)建了一個(gè)支持這種情況的后備機(jī)制,該機(jī)制通過 HTTP API 調(diào)用用戶的首選項(xiàng)服務(wù)。你應(yīng)該知道我在說什么吧。如今,該服務(wù)突然出現(xiàn)了巨大的流量尖峰,可能無法應(yīng)付所有的流量。更糟糕的是:你的服務(wù)可能接收到所有這些新請求,但是如果重試機(jī)制不能實(shí)現(xiàn)指數(shù)退避和抖動(dòng),那么你就可能遇到來自移動(dòng)應(yīng)用的分布式拒絕服務(wù)。

          9看到所有這些災(zāi)難,你還喜歡分布式系統(tǒng)嗎?

          要是我告訴你,我只是寫下了我所看到的災(zāi)難中的一小部分呢?分布式系統(tǒng)很難掌握,而且大多數(shù)軟件工程師只是在最近才持續(xù)接觸到它們。

          好消息是,對于我所說的很多災(zāi)難,我們都能找到解決方案,行業(yè)已經(jīng)創(chuàng)造除了更好的工具,使得除了美國五大科技巨頭(Facebook、蘋果、亞馬遜、Netflix、谷歌)之外的其他組織都能解決這些問題。

          我還是喜歡分布式系統(tǒng),而且我還是覺得微服務(wù)是一個(gè)解決組織問題的好方法。但是,當(dāng)我們把失敗看作“邊緣案例”或者我們認(rèn)為不可能發(fā)生的事時(shí),問題就出現(xiàn)了。在一定范圍內(nèi),這些邊緣案例成為新常態(tài),我們應(yīng)該加以應(yīng)對。

          原文鏈接:

          https://world.hey.com/joaoqalves/disasters-i-ve-seen-in-a-microservices-world-a9137a51

          瀏覽 57
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  性福五月天网址 | 亚洲精品乱码久久久久99 | 五月天六月婷婷 | 天天操夜| 久久影音先锋 |