自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我們什么時候應該轉(zhuǎn)向微服務?

開發(fā) 前端
避免小型單體反模式。微服務在多大規(guī)模上才有意義?避免比問題更糟糕的解決方案,并了解權(quán)衡取舍。

避免小型單體反模式。微服務在多大規(guī)模上才有意義?避免比問題更糟糕的解決方案,并了解權(quán)衡取舍。

上個月,我寫了一篇關于模塊化單體和現(xiàn)代單體架構(gòu)的價值的文章。該文章(和視頻)中出現(xiàn)的更有趣的討論之一是逆向討論:什么時候仍然選擇微服務是正確的?

與任何設計選擇一樣,答案是主觀的并且取決于很多因素。但是我們?nèi)匀豢梢允褂靡话愕慕?jīng)驗法則和全球指標。在我們進入這些問題之前,我們需要了解擁有微服務架構(gòu)意味著什么。然后我們可以衡量擁有這樣一個架構(gòu)的好處和代價。

一個常見的誤解是微服務只是簡單地分解為單體。事實并非如此。我和很多仍然持有這種觀點的人談過,公平地說,他們可能有道理。AWS 是這樣定義微服務的:

微服務是一種軟件開發(fā)的架構(gòu)和組織方法,其中軟件由通過定義明確的 API 進行通信的小型獨立服務組成。這些服務由獨立的小型團隊擁有。

微服務架構(gòu)使應用程序更易于擴展和更快地開發(fā),從而實現(xiàn)創(chuàng)新并加快新功能的上市時間。

較小的單體可能符合該定義,但如果您從字里行間中讀到,則它們不符合?!蔼毩ⅰ焙汀案子跀U展”這兩個詞暗示了這個問題。單體的問題(和優(yōu)勢)是單點故障。通過一項服務,我們通??梢愿菀椎匕l(fā)現(xiàn)問題。架構(gòu)要簡單得多。

如果我們將此服務分解成更小的部分,我們實際上會創(chuàng)建分布式故障點。如果鏈條上的一個部分出現(xiàn)故障,整個架構(gòu)就會崩潰。這不是獨立的,也不容易擴展。微服務不是小單體,分解單體不僅僅是處理較小的項目。這是關于改變我們的工作方式。

是什么造就了微服務?

一個好的微服務需要遵循以下健壯性和規(guī)模原則:

  • 按業(yè)務功能劃分:這是一個邏輯劃分。微服務是提供完整包的獨立“產(chǎn)品”。這意味著負責微服務的團隊可以在沒有依賴關系的情況下進行業(yè)務所需的所有更改。
  • 通過 CI/CD 實現(xiàn)自動化:如果沒有持續(xù)交付,更新成本將消除微服務的所有優(yōu)勢。
  • 獨立部署:這是隱含的,因為對一個微服務的提交只會觸發(fā)該特定服務的 CD。我們可以通過 Kubernetes 和基礎架構(gòu)即代碼 (IaC) 解決方案來實現(xiàn)這一點。
  • 封裝:它應該隱藏底層的實現(xiàn)細節(jié)。服務充當獨立產(chǎn)品,為其他產(chǎn)品發(fā)布 API。我們通常通過 REST 接口以及消息傳遞中間件來實現(xiàn)這一點。API 網(wǎng)關進一步增強了這一點。
  • 去中心化,沒有單點故障:否則,我們會分散故障。
  • 故障應該被隔離:否則,單個服務宕機可能會產(chǎn)生多米諾骨牌效應。斷路器可能是隔離故障的最重要工具。為了滿足這種依賴性,每個微服務都處理自己的數(shù)據(jù)。這意味著很多數(shù)據(jù)庫,有時可能具有挑戰(zhàn)性。
  • 可觀察的:這是處理大規(guī)模故障所必需的。沒有適當?shù)目捎^察性,我們實際上是盲目的,因為各個團隊可以自動部署。

這一切都很好,但實際上這意味著什么?

它的大部分意思是我們需要對我們處理一些重要想法的方式做出幾項重大改變。我們需要將更多的復雜性轉(zhuǎn)移給 DevOps 團隊。我們需要以不同的方式處理跨微服務的事務狀態(tài)。這是處理微服務時最難掌握的概念之一。

在理想的世界中,我們所有的操作都將很簡單,并包含在一個小型微服務中。圍繞我們的微服務的服務網(wǎng)格框架將處理所有全球復雜性并為我們管理我們的個人服務。但這不是真實的世界。實際上,我們的微服務可能具有在服務之間傳輸?shù)氖聞諣顟B(tài)。外部服務可能會失敗,為此,我們需要采取一些獨特的方法。

依賴 DevOps 團隊

如果您的公司沒有優(yōu)秀的 DevOps 和平臺工程團隊,微服務就不是一個選擇。由于遷移,我們可能會部署數(shù)百個應用程序,而不是部署一個應用程序。雖然單個部署簡單且自動化,但您仍然會在操作上投入大量工作。

當某些東西不起作用或無法連接時。當需要集成新服務或需要采用服務配置時。在使用微服務時,運營會承擔更大的負擔。這需要良好的溝通和協(xié)作。這也意味著管理特定服務的團隊需要重新承擔一些 OPS 負擔。這不是一項簡單的任務。

作為開發(fā)人員,我們需要了解許多用于將我們的單獨服務綁定回單個統(tǒng)一服務的工具:

  • 服務網(wǎng)格:讓我們組合獨立的服務,并有效地充當它們之間的負載均衡器。它還提供安全、授權(quán)、流量控制等功能。
  • API 網(wǎng)關:應該使用而不是直接調(diào)用 API。這有時會很尷尬,但通常對于避免成本、防止速率限制等來說是必不可少的。
  • 特征標志和秘密:在單體中也很有用。但如果沒有專用工具,它們就不可能在微服務規(guī)模上進行管理。
  • 熔斷:讓我們終止斷開的 Web 服務連接并優(yōu)雅地恢復。否則,單個損壞的服務可能會導致整個系統(tǒng)崩潰。
  • 身份管理必須是獨立的:在處理微服務環(huán)境時,您無法擺脫數(shù)據(jù)庫中的身份驗證表。

我將跳過編排、CI/CD 等,但它們也需要針對出現(xiàn)的每項服務進行調(diào)整。其中一些工具對開發(fā)人員來說是不透明的,但我們在所有階段都需要 DevOps 的幫助。

傳奇模式

無狀態(tài)服務將是理想的,承載狀態(tài)會使一切變得更加復雜。如果我們將狀態(tài)存儲在客戶端中,我們需要一直來回發(fā)送它。如果它在服務器上,我們將需要不斷獲取它、緩存它或?qū)⑵浔4嬖诒镜?,然后所有交互都將針對當前系統(tǒng)執(zhí)行。這消除了系統(tǒng)的可擴展性。

典型的微服務將存儲在自己的數(shù)據(jù)庫中并使用本地數(shù)據(jù)。需要遠程信息的服務通常會緩存一些數(shù)據(jù)以避免往返于其他服務。這是微服務可以擴展的最大原因之一。在單體中,數(shù)據(jù)庫應該成為應用程序的瓶頸,這意味著單體是高效的并且受限于我們存儲和檢索數(shù)據(jù)的速度。這有兩個主要缺點:

  • 大?。何覀儞碛械臄?shù)據(jù)越多;數(shù)據(jù)庫越大,性能會同時影響所有用戶。想象一下,查詢亞馬遜上每次購買的 SQL 表只是為了找到您的特定購買。
  • 域:數(shù)據(jù)庫有不同的用例。一些數(shù)據(jù)庫針對一致性、寫入速度、讀取速度、時間數(shù)據(jù)、空間數(shù)據(jù)等進行了優(yōu)化。跟蹤用戶信息的微服務可能會使用時間序列數(shù)據(jù)庫,該數(shù)據(jù)庫針對與時間相關的信息進行了優(yōu)化,而購買服務將專注于傳統(tǒng)的保守 ACID 數(shù)據(jù)庫。
  • 注意:一個整體可以使用多個數(shù)據(jù)庫。這可以很好地工作并且非常有用。但這是例外。不是規(guī)則。

saga 模式通過使用補償事務來撤銷 saga 失敗時的影響。當 saga 失敗時,將執(zhí)行補償事務以撤消前一個事務所做的更改。這允許系統(tǒng)從故障中恢復并保持一致的狀態(tài)。我們可以使用 Apache Camel 等工具來完成此操作,但這并非易事,并且需要比現(xiàn)代系統(tǒng)中的典型事務更多的參與。這意味著對于每個主要的跨服務操作,您都需要執(zhí)行等效的撤消操作來恢復狀態(tài)。那是不平凡的。有多種用于 saga 編排的工具,但這是一個超出本文范圍的大主題,我仍然會從廣義上對其進行解釋。

了解 saga 的重要之處在于它避免了經(jīng)典的 ACID 數(shù)據(jù)庫原則,而側(cè)重于“最終一致性”。這意味著操作會在某個時候使數(shù)據(jù)庫處于一致狀態(tài)。那是一個非常艱難的過程。想象調(diào)試一個只有在系統(tǒng)處于不一致狀態(tài)時才會出現(xiàn)的問題。

下圖從廣義上展示了這個想法。假設我們有一個匯款流程:

對于匯款,我們需要先分配資金。

然后我們驗證收件人是否有效且存在。

接下來,我們需要從我們的賬戶中扣除資金。

最后,我們需要將錢添加到收款人的帳戶中。

那就是一筆成功的交易。對于常規(guī)數(shù)據(jù)庫,這將是一個事務,我們可以在下圖中左側(cè)的藍色列中看到它。但如果出現(xiàn)問題,我們需要運行相反的過程:

如果分配資金失敗,我們需要移除分配。我們需要創(chuàng)建一個單獨的代碼塊來執(zhí)行分配的逆操作。

如果驗證收件人失敗,我們需要刪除該收件人。然后我們還需要刪除分配。

如果扣除資金失敗,我們需要恢復資金,移除接收者,移除分配。

最后,如果向收款人添加資金失敗,我們需要運行所有的撤銷操作!

saga 中的另一個問題在 CAP 定理中得到了說明。CAP 代表一致性、可用性和分區(qū)容錯性。問題是我們需要選擇任意兩個……別誤會我的意思,你可能三個都選。但是,在失敗的情況下,你只能保證兩個。

可用性意味著請求收到響應。但不能保證它們包含最新的寫入。

一致性意味著每次讀取都會收到最近的錯誤寫入。

容忍意味著即使許多消息在途中被丟棄,一切都會繼續(xù)工作。

這與我們處理交易失敗的歷史方法大不相同。

我們應該選擇微服務嗎?

希望您了解正確部署微服務有多么困難。我們需要做出一些重大妥協(xié)。這種新方式不一定更好,在某些方面,它更糟。但是微服務的支持者還是有道理的,我們可以通過微服務獲得很多,也應該關注這些好處。

我們預先提到了第一個要求:DevOps。擁有一支優(yōu)秀的 DevOps 團隊是考慮微服務的先決條件。我看到團隊試圖在沒有 OPS 團隊的情況下解決這個問題,他們最終花在操作復雜性上的時間比編寫代碼還多。這是不值得的努力。

微服務最大的好處是給團隊的。這就是為什么擁有穩(wěn)定的團隊和范圍至關重要的原因。將團隊拆分成獨立工作的垂直團隊是一個巨大的好處。世界上模塊化程度最高的單體無法與之抗衡。當我們有數(shù)百名開發(fā)人員單獨跟蹤 git 提交時,跟蹤代碼的規(guī)模變化就變得站不住腳了。微服務的價值只有在大團隊中才能體現(xiàn)出來。這聽起來很合理,但在創(chuàng)業(yè)環(huán)境中,事情突然發(fā)生了變化。我的一位同事在一家雇傭了數(shù)十名開發(fā)人員的初創(chuàng)公司工作。他們決定遵循微服務架構(gòu)并構(gòu)建了很多。然后是縮減和維護多種語言的數(shù)十種服務成為一個問題。

拆分單體很難但可行。將微服務統(tǒng)一到一個整體可能更難,我不知道有誰認真嘗試過這樣做但很想聽聽故事。

不是一個尺寸

要遷移到微服務架構(gòu),我們需要進行一些思維轉(zhuǎn)變。一個很好的例子是數(shù)據(jù)庫和用戶跟蹤微服務。在整體中,我們會將數(shù)據(jù)寫入表并繼續(xù)我們的工作。但這是有問題的。

隨著數(shù)據(jù)規(guī)模的擴大,這個用戶跟蹤表最終可能包含大量數(shù)據(jù),這些數(shù)據(jù)很難在不影響操作系統(tǒng)其余部分的情況下進行實時分析。通過微服務,我們可以提供幾個優(yōu)勢:

微服務的接口可以使用消息傳遞,這意味著發(fā)送跟蹤信息的成本將降至最低。

跟蹤數(shù)據(jù)可以使用時間序列數(shù)據(jù)庫,這對于這個用例來說會更有效。

我們可以流式傳輸數(shù)據(jù)并異步處理它以從該數(shù)據(jù)中獲取額外的價值。

存在復雜性,數(shù)據(jù)將不再本地化。因此,如果我們異步發(fā)送跟蹤數(shù)據(jù),我們需要發(fā)送所有必要的信息,因為跟蹤服務將無法返回到原始服務以獲取額外的元數(shù)據(jù)。但它具有位置優(yōu)勢,如果有關跟蹤存儲的法規(guī)發(fā)生變化,則只有一個地方可以存儲它。

動態(tài)控制和推出

您是否曾經(jīng)按下過發(fā)布按鈕導致生產(chǎn)中斷?

我做了不止一次(太多次了)。那是一種可怕的感覺。微服務在生產(chǎn)中仍然會失敗,并且仍然會發(fā)生災難性的失敗,但是,它們的失敗通常是局部的。將它們推廣到系統(tǒng)的特定子集 (Canary) 并進行驗證也更容易。這些都是可以由實際掌握用戶脈搏的人深入控制的策略:OPS。

微服務的可觀察性是必不可少的、昂貴的,但也更強大。由于一切都發(fā)生在網(wǎng)絡層,因此都暴露給可觀察性工具。SRE 或 DevOps 可以更詳細地了解故障。這是以開發(fā)人員為代價的,他們可能需要面對增加的復雜性和有限的工具。

應用程序可能會變得太大而不能失敗。即使采用模塊化,一些最大的單體應用也有如此多的代碼,運行一個完整的 CI/CD 周期需要數(shù)小時。然后,如果部署失敗,恢復到上一個好的版本也可能需要一段時間。

分割

過去,我們曾經(jīng)根據(jù)層級劃分團隊。客戶端、服務器、數(shù)據(jù)庫等。這是有道理的,因為每一個都需要一套獨特的技能。今天,垂直團隊更有意義,但我們?nèi)匀挥袑iL。

通常,移動開發(fā)人員不會在后端工作。但是假設我們有一個移動團隊想要使用 GraphQL 而不是 REST。對于單體,我們要么告訴他們“接受它”,要么我們必須完成這項工作。有了微服務,我們可以用很少的代碼為他們創(chuàng)建一個簡單的服務。核心服務的簡單外觀。我們不需要擔心移動團隊編寫服務器代碼,因為這相對孤立。我們可以對每個客戶層做同樣的事情,這樣更容易垂直整合一個團隊。

太大

很難將手指放在使整體式應用不切實際的尺寸上,但這是您應該問自己的問題:

我們擁有或想要多少支球隊?

如果你有幾個團隊,那么單體應用可能會很棒。如果您有十幾個團隊,那么您可能會在那里遇到問題。

衡量拉取請求和問題解決時間

隨著項目的增長,您的拉取請求將花費更多時間等待合并,并且問題將需要更長的時間來解決。這是不可避免的,因為項目的復雜性趨于增加。請注意,新項目將具有更大的功能,一旦您在項目統(tǒng)計中考慮到生產(chǎn)力的下降應該是可衡量的,這可能會影響結(jié)果。

請注意,這是一個指標。在許多情況下,它可以指示其他事情,例如需要優(yōu)化測試管道、審查流程、模塊化等。

我們有知道代碼的專家嗎?

在某個時候,一個龐大的項目變得如此之大,以至于專家們開始忘記細節(jié)。當錯誤變得難以為繼并且沒有權(quán)威人物可以不經(jīng)咨詢就做出決定時,這就成為一個問題。

你愿意花錢嗎?

微服務將花費更多。沒有辦法解決這個問題。在某些特殊情況下,我們可以調(diào)整規(guī)模,但最終,可觀察性和管理成本將消除任何潛在的成本節(jié)約。由于人員成本通常超過云托管成本,因此總成本可能仍對您有利,因為如果規(guī)模足夠大,這些成本可能會降低。

取舍

下面的雷達圖很好地說明了單體與微服務的權(quán)衡。請注意,此圖表是為大型項目設計的。項目越小,單體應用的前景就越好。

請注意,微服務在容錯和團隊獨立性方面為大型項目帶來了好處。但他們付出了代價。他們可以減少研發(fā)支出,但他們主要將其轉(zhuǎn)移到 DevOps,因此這并不是一個主要的好處。

最后一句話

微服務的復雜性是巨大的,有時會被實施團隊忽略。開發(fā)人員使用微服務作為一個大棒來拋棄他們不想維護的系統(tǒng)部分,而不是構(gòu)建一個可持續(xù)的、可擴展的架構(gòu)來取代單體。

我堅信項目應該從單體開始。微服務是擴展團隊的優(yōu)化,過早優(yōu)化是萬惡之源。問題是,什么時候做這樣的優(yōu)化合適?

我們可以使用一些指標來簡化決策。最終,這種變化不僅僅是拆分單體。這意味著重新思考交易和核心概念。從單體開始,我們就有了一個藍圖,我們可以使用它來調(diào)整我們的新實現(xiàn),因為它會加強。

責任編輯:華軒 來源: 今日頭條
相關推薦

2022-09-27 15:06:07

微服務架構(gòu)開發(fā)

2012-07-26 10:27:31

PHP

2022-08-29 10:35:42

微服務架構(gòu)單體應用

2015-10-20 15:59:57

注釋代碼程序

2015-10-26 09:38:52

避免注釋代碼

2021-01-30 19:59:37

性能項目開源

2010-11-09 13:58:03

SQL Server鎖

2020-06-17 10:35:16

機器學習AI人工智能

2023-04-24 14:32:54

2024-09-02 08:53:44

2020-05-12 11:25:50

MySQLES數(shù)據(jù)庫

2017-05-15 09:55:07

2016-01-20 09:54:51

微服務架構(gòu)設計SOA

2019-04-04 12:59:03

微服務企業(yè)數(shù)字化

2024-11-07 12:08:27

微服務協(xié)議通信

2023-02-14 07:31:30

ARMx86蘋果

2015-07-08 15:55:01

NSStringcopystrong

2022-06-27 16:55:30

5G6G

2013-11-28 16:03:24

2012-09-24 10:20:39

JavaScriptJS
點贊
收藏

51CTO技術棧公眾號