論如何正確實施微服務架構的10個技巧? 作者 | Md Kamaruzzaman 譯者 | 蘇本如,責編 | Elle 出品 | CSDN(ID:CSDNnews) 以下為譯文: 微服務架構到底是什么呢?以下是我給出的定義: 微服務架構是將軟件系統(tǒng)分解為自主模塊,自主模塊可以獨立部署,通過輕量級的、與語言無關的方式進行通信,共同實現(xiàn)業(yè)務目標。 軟件系統(tǒng)通常非常復雜。由于人腦只能處理一定程度的復雜性,因此大型軟件系統(tǒng)的高復雜性會帶來很多問題。一個大型的、復雜的軟件系統(tǒng)通常很難開發(fā)、增強、維護、難以實現(xiàn)現(xiàn)代化和規(guī)?;?。許多年來,人們作了很多嘗試,以解決軟件系統(tǒng)的復雜性難題。 20世紀70年代,David Parnas和Edsger W. Dijkstra引入了模塊化軟件開發(fā),來解決這一復雜性問題。20世紀90年代,為了解決業(yè)務應用的復雜性,引入了分層軟件架構。 到了21世紀初,面向服務的體系結構(Service-Oriented Architecture,SOA)成為開發(fā)復雜業(yè)務應用程序的主流。而微服務架構則是處理現(xiàn)代軟件應用復雜性的最新方法。那么可能有人會問:為什么我們突然需要一種新的軟件開發(fā)方法呢? 簡單來說,這是因為在過去的十年里,軟件開發(fā)所處的生態(tài)系統(tǒng)發(fā)生了巨大的變化?,F(xiàn)在,軟件通常是使用敏捷方法開發(fā),使用CI/CD方法部署在容器 云(Container Cloud)上,數(shù)據(jù)保存在NoSQL數(shù)據(jù)庫上,最后呈現(xiàn)在現(xiàn)代瀏覽器或智能手機上,并且這些機器通過高速網(wǎng)絡連接在一起。 基于這些因素,微服務架構于2012年應運而生。 微服務vs.單一體系架構 對于微服務架構與單一體系架構,兩類人的觀點截然相反。一類人認為,微服務架構是一種盲目模仿(Cargo-Cult)、或者趨勢驅動(Hype Driven)式的開發(fā)方式,對于技術上癮的開發(fā)人員來說,它就像他們的游樂場。而對于另一類人來說,微服務架構是“一個架構搞定一切”,它可以消除任何軟件系統(tǒng)的復雜性。而筆者認為,微服務架構和單一體系架構可以互為補充。對于長期而言都很精簡的應用程序,單一體系架構可能更為合適。而另一方面,對于大型而且復雜的應用程序,或者有可能變得大而復雜的應用程序,微服務架構這一解決方案更加有效?,F(xiàn)今的軟件開發(fā)通常是十分龐大的工程,以至于微服務架構和單一體系架構可以實現(xiàn)共存,就像SQL和NoSQL數(shù)據(jù)庫的共存一樣。 10個最佳實踐 正確地設計微服務架構是一項非常困難和具有挑戰(zhàn)性的工作。和為所有問題提供一勞永逸解決方案的單一體系架構相反,微服務體系架構針對不同的問題提供了不同的解決方案。如果選擇了錯誤的解決方案,那么微服務架構就將是一顆定時炸彈,注定要引爆。一個設計有缺陷的微服務架構比單一體系架構更加糟糕。為微服務架構定義一組最佳實踐也是一項挑戰(zhàn)。我看過一些會議演講,其中有一些著名和受人尊敬的軟件工程師們提出過一些關于微服務架構的最佳實踐,但結果適得其反。 在本文中,我將提出一些微服務架構的最佳實踐,這些實踐將有助于開發(fā)有效的微服務應用程序,其中目標項目的預期壽命將會超過6個月,團隊規(guī)模從中等到大型(6名以上的開發(fā)人員)。 在這里,我也將列出一些關于微服務架構最佳實踐的帖子供大家參考,例如Martin Fowler撰寫的《微服務架構的特征》、Chris Richardson撰寫的《微服務模式》、和Tony Mauro撰寫的《在Netflix上采用微服務:架構設計的若干教訓》。也有一些很棒的演講,例如Stefan Tilkov的演講《微服務模式和反模式》,David Schmitz的演講《應對微服務嚴重失敗的10條技巧》,Sam Newman的演講《微服務原理》。此外,我還編寫了一份精心挑選的書籍清單,這些書籍對于理解微服務架構設計的以下10個最佳實踐必不可少: 1. 領域驅動設計(DDD:Domain-Driven Design) 開發(fā)微服務的最重要的挑戰(zhàn)是將一個大型、復雜的應用程序拆分成小型、自主管理的、并且可以獨立部署的模塊。 如果應用程序沒有以正確的方式進行拆分,那么產生的微服務將會是緊密耦合的,它們將會同時具有單一體系架構的所有缺點和微服務的所有復雜性,這種架構被稱為分布式單一體系架構(Distributed Monolith)。 幸運的是,在這方面已經(jīng)有一些可以大有幫助的解決方案。Eric Evans是一名軟件工程顧問,他曾在不同公司中多次遇到有關業(yè)務應用程序中復雜性的問題,并在2004年出版的書籍《領域驅動設計:解決軟件核心的復雜性》中總結了一些寶貴的見解。該書概述了以下三個核心概念: 軟件開發(fā)團隊應與業(yè)務部門或領域專家密切合作。 架構師/開發(fā)人員和領域專家應首先進行戰(zhàn)略設計:找到有界的上下文和相關的核心域、通用語言、子域、上下文映射等等。 然后,架構師/開發(fā)人員應進行戰(zhàn)術設計,將核心領域分解為細粒度的構建塊:如實體(Entity)、值對象(Value Object)、聚合(Aggregate)、聚合根(Aggregate Root)等等。 領域驅動設計的詳細討論超出了這篇文章的范圍,但是你可以閱讀Eric Evans撰寫的關于領域驅動設計的早期著作:《領域驅動設計:解決軟件核心的復雜性》(藍皮書),或者閱讀更現(xiàn)代一點的,由Vaughn Vernon撰寫的《領域驅動設計之實施》一書(紅皮書)。 如果將一個大型系統(tǒng)劃分為核心域和子域,然后將核心域和子域映射到一個或多個微服務上,那么就可以得到理想的松耦合微服務。 2. 微服務的數(shù)據(jù)庫 將復雜的應用程序拆分為微服務模塊后,下一個挑戰(zhàn)就出現(xiàn)了 -- 如何處理數(shù)據(jù)庫?是否應該在微服務之間共享數(shù)據(jù)庫?這個問題的答案是把雙刃劍,有利有弊。 一方面,微服務之間共享數(shù)據(jù)庫,會導致微服務之間的強耦合,這與微服務體系架構的目標正好相反。即使數(shù)據(jù)庫中出現(xiàn)微小變化,也需要團隊之間的同步操作。 而且,在一個服務中管理事務和鎖定數(shù)據(jù)庫就已經(jīng)足夠具有挑戰(zhàn)性了,管理多個分布式微服務之間的事務和鎖定更是一項極其艱巨的任務。 另一方面,如果每個微服務都有自己的數(shù)據(jù)庫/私有表,那么在微服務之間交換數(shù)據(jù)就相當于打開了潘多拉的魔盒。 因此,許多著名的軟件工程師都主張在微服務之間共享數(shù)據(jù)庫,以此作為一種實用的解決方案。但是,在我看來,微服務本質上是一個可持續(xù)和長期的軟件開發(fā)過程,因此,每個微服務都應該有自己的數(shù)據(jù)庫(或私有表)。 3. 微前端 不幸的是,大多數(shù)后端開發(fā)人員都對前端開發(fā)都有一個過時的看法,認為前端開發(fā)很簡單。 由于大多數(shù)軟件架構師都是后臺開發(fā)人員,所以他們很少考慮前端,在架構設計中往往忽略前端。在微服務項目中,后端及其和數(shù)據(jù)庫的交互通常會很好地模塊化,但前端只有一個單一整體。 在最好的情況下,開發(fā)人員會考慮使用最熱門的SPA(React,Angular,Vue)之一來開發(fā)這個單一的前端。這種方法的主要問題在于前端的單一架構和后端的單一架構一樣的糟糕,正如我之前所描述的。 此外,當前端需要適應瀏覽器的變化而進行現(xiàn)代化更新時,它就需要進行一場大爆炸式的更新(這就是為什么許多公司仍然使用過時的Angular 1框架的原因)。 前端簡單但功能非常強大,并提供了固有的嵌入。開發(fā)基于SPA的微前端有很多方法:使用iFrame、Web組件或借助Elements(Angular/React)。 4. 持續(xù)交付 微服務架構的關鍵USP(獨特賣點)之一是每個微服務都可以獨立部署。如果你有一個由100個微服務組成的系統(tǒng),并且只需要更改一個微服務,那么你可以只更新一個而無需更改其他99個微服務。 但是,在沒有任何自動化系統(tǒng)(DevOps,CI/CD)幫助的情況下獨立部署100個微服務是一項艱巨的任務。要充分利用此微服務功能,需要采用CI/CD和DevOps系統(tǒng)。使用不帶CI/CD、DevOps系統(tǒng)的微服務架構,就像購買最新的保時捷,然后用手剎來駕駛它。 難怪微服務專家Martin Fowler將CI/CD列為使用微服務體系架構的三個先決條件之一。 5. 可觀察性 微服務架構的一個主要缺點是,軟件開發(fā)變得簡單,但卻犧牲了運營。對于單一架構來說,對應用程序的監(jiān)控要簡單得多。 但是由于很多微服務在容器上運行,整個系統(tǒng)的可觀察性變得非常關鍵和復雜。 甚至日志記錄也變得復雜,無法將許多容器/機器中的日志聚合到一個中心位置。幸運的是,現(xiàn)在市場上已經(jīng)有很多企業(yè)級解決方案。例如,ELK/Splunk可以提供微服務日志記錄。 Prometheus/App Dynamics可以提供行業(yè)級的監(jiān)控。微服務領域中另一個非常關鍵的可觀察性工具是Tracing。 通常,對微服務的一個API請求會導致對其他微服務的多個級聯(lián)調用。要分析微服務系統(tǒng)的延遲,必須測量每個微服務的延遲。Zipkin/Jaeger為微服務提供了出色的跟蹤支持。 6. 統(tǒng)一技術棧 微服務架構要求,對于一個微服務,需要采用最適合該微服務的編程語言和框架。這句話不應該只從字面上理解。 有時,微服務可能需要一個新的技術堆棧,例如對于CPU繁重/高性能的任務,可以選擇像C / Rust這樣的編程語言。如果一個微服務是為機器學習服務,那么Python也許是一個更好的選擇。 但是,如果沒有充分的理由使用不同的編程語言/框架,可能會導致太多的編程語言和框架, 而沒有帶來任何實質性的好處。想象一下, 如果一個微服務是用Spring Boot Kotlin React MySQL開發(fā)的,另一個是用JakartaEE Java Angular PostgreSQL開發(fā)的,再另一個又是用Scala Play Framework VueJS Oracle開發(fā)的,那么維護這么多不同的編程語言、數(shù)據(jù)庫和框架需要付出巨大的努力,但收獲卻很小。 7.異步通信 微服務架構中最具挑戰(zhàn)性的設計決策之一是服務之間如何通信和共享數(shù)據(jù)。當每個微服務都有自己的數(shù)據(jù)存儲時,這一點尤為重要。 通常,一個微服務可以單獨存在,但卻不能單獨實現(xiàn)所有的業(yè)務目標。所有的微服務需要協(xié)同工作才能實現(xiàn)業(yè)務目標。 而為了協(xié)同工作,它們需要交換數(shù)據(jù)或觸發(fā)其他微服務來完成任務。微服務之間最簡單和最常見的通信方式是通過同步REST API,這種方法很實用,但不是長久之計。 如果服務A調用服務B,服務B調用服務C,服務C同步調用服務D,那么延遲就會疊加。此外,由于微服務大多是分布式系統(tǒng),它們可能會失敗。 所以同步微服務經(jīng)常會導致故障級聯(lián)(failure cascading),即一個服務中的故障可能會導致其他服務中的故障。 微服務之間的同步通信還會導致微服務之間的緊密耦合。對于長期解決方案,微服務應該采用異步通信。 微服務之間的異步通信有多種方式:通過消息隊列(如Kafka)、通過異步REST(ATOM)或者CQRS。 8. 微服務優(yōu)先 許多專家認為,對于新建項目,最好從松散耦合的單一體系架構開始,因為微服務體系架構需要大量的初始工作來設置運營。在他們看來,一旦項目足夠成熟,“精心”設計的單一架構可以很容易地轉換為微服務架構。然而,在我看來,這種方法在大多數(shù)情況下都會失敗。在實際應用中,單一架構系統(tǒng)內部的模塊將緊密耦合,這會導致很難將其轉換為微服務架構。另外,一旦應用程序投入生產,在不中斷應用程序的情況下,將其轉換為微服務將更加困難。所以,如果最終有計劃使用微服務架構,我的建議是從一開始就采用微服務架構。 9. 基于庫的基礎設施 在微服務軟件開發(fā)的早期,Netflix主要使用Java編程來開發(fā)微服務。他們還開發(fā)了許多庫(Netflix OSS Stack,包括Hystrix、Zuul)。 許多公司效仿Netflix,開始使用Netflix OSS庫。后來,許多公司(包括Netflix)發(fā)現(xiàn),由于Java的體積龐大和冷啟動問題,它并不是開發(fā)微服務的合適語言。 Netflix后來轉向Polyglot微服務范式,并決定不再進一步開發(fā)Netflix OSS,這導致追隨Netflix的公司陷入困境。 因此,與其在特定語言庫(如基于Java的Netflix OSS)上投入巨資,不如使用框架(如服務網(wǎng)格、API網(wǎng)關)更為明智。 10. 組織考慮 大約50年前(1967年),梅爾文·康威(Melvin Conway)觀察到公司的軟件架構受到組織結構的制約(康威定律)。 雖然這項觀察已有50年歷史,但麻省理工學院和哈佛商學院最近發(fā)現(xiàn),該定律在現(xiàn)代仍然有效。如果一個組織計劃開發(fā)微服務架構,那么它應該相應地確定團隊規(guī)模(兩個“美式”披薩團隊的大?。?人或9人)。 另外,團隊應該是跨職能的,理想情況下應該擁有前端/后端開發(fā)人員、運維人員和測試人員。只有在高層管理者也相應地改變他們的觀點和愿景的情況下,微服務架構才能發(fā)揮作用。 原文:https:///effective-microservices-10-best-practices-c6e4ba0c6ee2 本文為 CSDN 翻譯,轉載請注明來源出處。 【End】 熱 文推 薦 |
|
來自: yi321yi > 《系統(tǒng)》