歡迎光臨
每天分享高質量文章

關於微服務架構,你需要關註的那些點

來自:開源中國
https://www.oschina.net/question/2720166_2283418

今天談到系統架構樣式,很難不聯想起微服務架構。企業或組織在系統架構的實踐過程中,從最初的單體架構,之後走向 SOA,逐漸分佈式之後,最終產生了微服務架構。

微服務架構的出現,為應對快速變化的業務需求、冗長的開發周期提供了一種新的解決方案,它以模塊化的思維應對快速變化的業務需求,解耦系統之間各個子系統、業務、資料庫,甚至開發團隊,使用如自動化部署、自動化業務監控預警、呼叫鏈監控、容器化,以及敏捷開發等思想加快軟體的開發周期,實現更快速、更高質量的交付,成為當下最流行的架構風格之一。

微服務架構如此火熱,開發者想要瞭解其相關知識點,可以通過看書、學習各個公司的實踐經驗,或者請教有經驗的專家,要不就去聽技術會議分享,同時網上也有很多相關理論與實踐總結可以查看。

而我們之前通過網站上“高手問答”這一欄目,為大家提供了一個集中式向專家提問的機會,讓更多人能夠直接面對專家,提升微服務架構相關能力。當期觀眾提問與專家的回答有許多精彩之處,故整理出此文,以饗讀者。

Q:微服務架構和傳統的 SOA 架構有什麼區別?

面向服務的架構(SOA)是一個組件模型,它將應用程式的不同功能單元(稱為服務)通過這些服務之間定義良好的接口和契約聯繫起來。接口是採用中立的方式進行定義的,它應該獨立於實現服務的硬體平臺、操作系統和編程語言。這使得構建在各種各樣系統中的服務可以以一種統一和通用的方式進行交互。

都是做服務化,那麼微服務與 SOA 的異同有哪些呢?

相同點

  • 需要 Registry,實現動態的服務註冊發現機制。

  • 需要考慮分佈式下麵的事務一致性,CAP 原則下,兩段式提交不能保證性能,事務補償機制需要考慮。

  • 同步呼叫還是異步訊息傳遞,如何保證訊息可靠性?SOA 由 ESB 來集成所有的訊息。

  • 都需要統一的 Gateway 來匯聚、編排接口,實現統一認證機制,對外提供 APP 使用的 RESTful 接口。

  • 同樣要關註如何再分佈式下定位系統問題,如何做日誌跟蹤?就像電信領域做了十幾年的信令跟蹤的功能。

    差異點

    • 是持續集成、持續部署?對於 CI、CD(持續集成、持續部署),這本身和敏捷、DevOps 是交織在一起的,所以更傾向於軟體工程的領域而不是微服務技術本身。

    • 使用不同的通信協議是不是區別?微服務的標桿通信協議是 RESTful,而傳統的 SOA 一般是 SOAP,不過目前來說採用輕量級的 RPC 框架(Dubbo、Thrift、gRPC)非常多,在 Spring Cloud 中也有 Feign 框架將標準 RESTful 轉為代碼的 API 這種仿 RPC 的行為,這些通信協議不應該是區分微服務架構和 SOA 的核心差別。

    • 是流行的基於容器的框架還是虛擬機為主?Docker 虛擬機和物理機都是架構實現的一種方式,不是核心區別。

      SOA 和微服務的一個主要不同點就是自動化程度上的不同。大部分的 SOA 實現只達到服務級別的抽象,而微服務達到了對實現和運行環境的抽象級別。

      在一個規範的微服務中,每個微服務應該被構建成胖 JAR(fat JAR),其中內置了所有的依賴,然後作為一個單獨的 Java 行程存在。

      Q:微服務業務層如何進行分層?業務系統如何定級,標準為什麼?

      一般微服務的分層需要根據公司的自身情況。

      同一公司使用統一應用分層,以減少開發維護學習成本。應用分層看起來很簡單,但每個程式員都有自己的一套方法,哪怕是初學者,所以想實施起來並非那麼容易。

      最早接觸的分層架構應該是我們最熟悉的 MVC(Model-View-Controller)架構,其將應用分成了模型、視圖和控制層,可以說引導了絕大多數開發者。而現在的應用(包括框架)中非常多架構設計都使用此樣式。之後又演化出了 MVP(Model-View-Presenter)和 MVVM(Model-View-ViewModel)。這些可以說都是隨著技術的不斷發展,為了應對不同場景所演化出來的模型。

      而微服務的每個架構都可以再細分成領域模型,下麵看一下經典的領域模型架構。

      它包括了 Domain、Service 和 Repositories。核心物體(Entity)和值物件(Value Object)應該在 Domain 層,定義的領域服務(Domain Service)在 Service 層,而針對物體和值物件的儲存和查詢邏輯都應該在 Repositories 層。

      值得註意的是,不要把 Entity 的屬性和行為分離到 Domain 和 Service 兩層中去實現,即所謂的貧血模型,事實證明這樣的實現方式會造成很大的維護問題。基於這種設計,工程的結構可以構造為:

      當然,在微服務的架構中,每個微服務不必嚴格遵照這樣的規定,切忌死搬硬套,最重要的是理解業務。在不同的業務場合,架構的設計可以適當地調整,畢竟適合的架構一定要具有靈活性。

      分層的原則如下:

      檔案夾分層法

      應用分層採用檔案夾方式的優點是可大可小、簡單易用、統一規範,可以包括5個專案,也可以包括50個專案,以滿足所有業務應用的多種不同場景。

      呼叫規約

      在開發過程中,需要遵循分層架構的約束,禁止跨層次的呼叫。

      下層為上層服務

      以用戶為中心,以標的為導向。上層(業務邏輯層)需要什麼,下層(資料訪問層)就提供什麼,而不是下層(資料訪問層)有什麼,就向上層(業務邏輯層)提供什麼。

      物體層規約

      Entity 是資料表物件,不是資料訪問層物件;DTO 是網絡傳輸物件,不是表現層物件;BO 是記憶體計算邏輯物件,不是業務邏輯層物件,不是只能給業務邏輯層使用。如果僅限定在本層訪問,則導致單個應用內大量沒有價值的物件轉換。以用戶為中心來設計物體類,可以減少無價值重覆物件和無用轉換。

      U型訪問

      下行時表現層是 Input,業務邏輯層是 Process,資料訪問層是 Output。上行時資料訪問層是 Input,業務邏輯層是 Process,表現層是 Output。

      Q:微服務的粒度到底怎麼劃分,有什麼經驗嗎?

      這個也是個設計問題,首先是業務必須熟悉,然後可以根據領域模型進行領域劃分,拆分可以根據 AKF 擴展立方體(Scalability Cube)。

      這個立方體有三個軸線,每個軸線描述擴展性的一個維度,他們分別是產品、流程和團隊:

      • X軸 —— 代表無差別的克隆服務和資料,工作可以很均勻的分散在不同的服務實體上;

      • Y軸 —— 關註應用中職責的劃分,比如資料型別,交易執行型別的劃分;

      • Z軸 —— 關註服務和資料的優先級劃分,如分地域劃分。

      

      三個維度擴展的對比

      通過這三個維度上的擴展,可以快速提高產品的擴展能力,適應不同場景下產品的快速增長。不同維度上的擴展,有著不同的優缺點:

      X軸擴展

      • 優點:成本最低,實施簡單;

      • 缺點:受指令集多少和資料集大小的約束。當單個產品或應用過大時,服務響應變慢,無法通過X軸的水平擴展提高速度;

      • 場景:發展初期,業務複雜度低,需要增加系統容量。

      Y軸擴展

      • 優點:可以解決指令集和資料集的約束,解決代碼複雜度問題,可以實現隔離故障,可以提高響應時間,可以使團隊聚焦更利於團隊成長;

      • 缺點:成本相對較高;

      • 場景:業務複雜,資料量大,代碼耦合度高,團隊規模大。

      Z軸擴展

      • 優點:能解決資料集的約束,降低故障風險,實現漸進交付,可以帶來最大的擴展性。

      • 缺點:成本最昂貴,且不一定能解決指令集的問題;

      • 場景:用戶指數級快速增長。

        如何將理論付諸實踐?

        為擴展分割應用

        • X軸:從單體系統或服務,水平克隆出許多系統,通過負載均衡平均分配請求;

        • Y軸 :面向服務分割,基於功能或者服務分割,例如電商網站可以將登陸、搜索、下單等服務進行Y軸的拆分,每一組服務再進行X軸的擴展;

        • Z軸 :面向查找分割,基於用戶、請求或者資料分割,例如可以將不同產品的SKU分到不同的搜索服務,可以將用戶哈希到不同的服務等。

          為擴展分割資料庫 

          • X軸:從單庫,水平克隆為多個庫上讀,一個庫寫,通過資料庫的自我複製實現,要允許一定的讀寫時延;

          • Y軸 :根據不同的信息型別,分割為不同的資料庫,即分庫,例如產品庫,用戶庫等;

          • Z軸 :按照一定演算法,進行分片,例如將搜索按照MapReduce的原理進行分片,把SKU的資料按照不同的哈希值進行分片儲存,每個分片再進行X軸冗餘。

            為擴展而快取

            在理想情況下,處理大流量最好的方法是通過高速快取來避免處理它。從架構層面看,我們能控制的主要有以下三個層次的快取:

            • 物件快取:物件快取用來儲存應用的物件以供重覆使用,一般在系統內部,通過使用應用快取可以幫助資料庫和應用層卸載負載。

            • 應用快取:應用快取包括代理快取和反向代理快取,一個在用戶端,一個在服務端,標的是提高性能或減少資源的使用量。

            • 內容交付網絡快取:CDN 的總原則是將內容推送到盡可能接近用戶終端的地方,通過不同地區使用不同ISP的網關快取,達到更快的響應時間和對源服務的更少請求。

              為擴展而異步

              • 同步改異步:同步呼叫,由於呼叫間的同步依賴關係,有可能會導致雪崩效應,出現一系列的連鎖故障,進而導致整個系統出現問題,所以在進行系統設計時,要盡可能的考慮異步呼叫方式,郵件系統就是一個非常好的異步呼叫例子。

              • 應用無狀態:當進行 AKF 擴展立方體的任何一個軸上的擴展時,都要首先解決應用的狀態問題,即會話的管理,可以通過避免、集中和分散的方式進行解決。

              Q:微服務怎麼實現事務管理的?

              其實微服務的事務就是分佈式事務,剛性事務和柔性事務。

              剛性事務是指嚴格遵循 ACID 原則的事務,例如單機環境下的資料庫事務。柔性事務是指遵循 BASE 理論的事務,通常用在分佈式環境中,常見的實現方式有:兩階段提交(2PC),TCC 補償型提交,基於訊息的異步確保型,最大努力通知型。

              資料一致性分為以下幾種情況:

              強一致性

              當更新操作完成之後,任何多個後續行程或者執行緒的訪問都會傳回最新的更新過的值。這種是對用戶最友好的,就是用戶上一次寫什麼,下一次就保證能讀到什麼。根據 CAP 理論,這種實現需要犧牲可用性。

              弱一致性

              系統並不保證後續行程或者執行緒的訪問都會傳回最新的更新過的值。系統在資料寫入成功之後,不承諾立即可以讀到最新寫入的值,也不會具體地承諾多久之後可以讀到。

              最終一致性

              弱一致性的特定形式。系統保證在沒有後續更新的前提下,系統最終傳回上一次更新操作的值。在沒有故障發生的前提下,不一致視窗的時間主要受通信延遲、系統負載和複製副本的個數影響。DNS 是一個典型的最終一致性系統。

              分佈式事務的各種實現方式:

              • 如果業務場景需要強一致性,那麼儘量避免將它們放在不同服務中,也就是儘量使用本地事務,避免使用強一致性的分佈式事務。

              • 如果業務場景能夠接受最終一致性,那麼最好是使用基於訊息的最終一致性的方案(異步確保型)來解決。

              • 如果業務場景需要強一致性,並且只能夠進行分佈式服務部署,那麼最好是使用 TCC 方案而不是 2PC 方案來解決。

              Q:在基於 Spring Cloud 的微服務架構中,使用 Docker 和 k8s 這些容器化技術能帶來哪些方面的好處?對於中小規模的微服務架構中,是否有使用它們的必要性呢?

              容器技術不是模仿硬體層次,而是在 Linux 內核里使用 cgroup 和 namespaces 來打造輕便的、將近裸機速度的虛擬技術操作系統環境。因為不是虛擬化儲存,所以容器技術不會管底層儲存或者檔案系統,而是你放哪裡,它操作哪裡。

              也就是說,它能更細粒度地控制 Linux,能夠做到按需分配,我們企業級開發種經常面臨的一個問題就是資源不足,而使用 Docker 可以更加有效地利用資源。這個跟企業的規模個人感覺不是很大。

              Q:微服務樣式下資料庫的管理,多個服務之間的資料聚合怎麼做才能避免資料過於分散導致查詢實現困難?感覺 k8s 可以代替 Spring Cloud 的一些組件(比如均衡負載、配置服務、服務發現),如何才能分清它們之間的關係?

              資料聚合其實涉及到微服務的一種設計樣式,微服務的設計樣式主要有以下幾種:鏈式設計樣式、聚合器設計樣式、資料共享設計樣式和異步訊息控制樣式。

              聚合器設計樣式是將請求統一由網關路由到聚合器,聚合器向下路由到指定的微服務中獲取結果,並且完成聚合。首頁展現、分類搜索和個人中心等通常都使用這種設計。

              

              資料共享樣式也是微服務設計樣式的一種。應用通過網關呼叫多個微服務,微服務之間的資料共享通過同一個資料庫,這樣能夠有效地減少請求次數,並且對於某些資料量小的情況非常適合。

              

              也就是說,服務需要經過一定的設計處理。可以再網關部分實現資料查詢的路由。

              說到 k8s 和 Spring Cloud,兩個平臺在核心領域都很強,並且在其它領域改進。Spring Cloud 可以快速使用、對開發者友好,然而 Kubernetes 對 DevOps 友好,艱難的學習曲線,但是改寫更廣泛的微服務障礙。以下是這些點的總結。

              

              兩種架構處理了不同範圍的 MSA 障礙,並且它們從根本上用了不同的方法。Spring Cloud 方法是試圖解決在 JVM 中每個 MSA 挑戰,而 Kubernetes 方法是試圖讓問題消失,為開發者在平臺層解決。Spring Cloud 在 JVM 中非常強大,Kubernetes 管理那些 JVM 很強大。同樣的,它就像一個自然發展,結合兩種工具並且從兩個專案中最好的部分受益。

              Q:請教一下,關於微服務架構中的 Service Mesh,它有哪些優勢呢?

              Service Mesh 最終並不是引入一項新功能,而是功能定位的轉變。首先我們要知道 Web 應用程式總是必須管理服務間通信的複雜性。

              Service Mesh 是一個網絡模型,它是位於 TCP/IP 之上的抽象層,它假定底層的 L3/L4 網絡是真實存在的,並且能夠點對點地傳遞位元組。但與 TCP 不同的是,Service Mesh 具有更高的性能。

              它以專用基礎設施層的形式存在,通常作為一組輕量級高性能網絡代理,這些代理和程式代碼部署在一起,但是應用程式不需要對代理有任何動作,它被用來處理服務間通訊,通過複雜的拓撲結構讓請求傳遞的過程變得更可靠。

              你可以思考下2000年的中型 Web 應用程式的典型架構: 三層應用程式。 在這個模型中,應用程式邏輯、Web 服務邏輯和儲存邏輯都是單獨的一層,層之間的通信雖然複雜,但這種複雜性是限定在一定範圍內,因為畢竟只有兩個跳轉。這裡沒有“網格”(Mesh),但是在每個層的代碼中處理的跳轉之間有通信邏輯。

              當這種架構方式在面對應用程式內部邏輯越來越複雜化的情形時,它就開始崩潰了。 像 Google、Netflix 和 Twitter 這樣的公司無時無刻都面臨著巨大的流量需求,它們實現了雲原生方案的前身:應用層被分解成許多服務(有時稱為“微服務”),層級間則形成了一個拓撲結構。

              在這些系統中,廣義的通訊層突然變得相關起來,但通常以“胖客戶端”的庫集(library)形式出現, 比如 Twitter 的 Finagle、Netflix 的 Hystrix,以及 Google 的 Stubby 就是這樣的例子。

              從很多方面上來講,像 Finagle、Stubby 和 Hystrix 這些庫集其實是 Service Mesh 的雛形。雖然它們受其周圍環境的細節影響,並且需要使用特定的語言和框架,但是它們是用於管理服務到服務間通信的專用基礎設施,並且(在開源 Finagle 和 Hystrix 庫集的情形下)可以在其公司之外使用。

              到了雲原生應用時期,雲原生模型本身結合了許多小型服務的微服務方法和兩個額外的因素:容器(例如 Docker),它提供了資源隔離和依賴關係管理,以及一個編排層(例如 Kubernetes),它將底層硬體抽象出了一個同質池。

              這三個組件支持應用程式在負載下可彈性伸縮的自然機制, 並能夠處理雲平臺環境中存在的部分故障。

              但面對數百個服務或數千個實體,和隨時在重新安排實體的編排層,單個請求經由服務拓撲的路徑可能非常複雜,而由於容器使每個服務用不同的語言寫入處理變得更容易了,庫集方法也就不再可行了。

              這種複雜性和關鍵性的結合,激發了對服務到服務間通信的專用基礎層的需求,這個專用層與應用程式代碼分離出來,並能夠捕捉底層環境的高度動態特性。就是這一專用層我們稱之為 Service Mesh。這樣 Service Mesh 的優勢自然也就可以瞭解了。

              Q:我是來自於一家中小企業的運維和開發人員,一直對微服務架構很感興趣,請問一下如果我們企業將來打算採用微服務架構,我們將面臨著哪些挑戰?

              面臨的挑戰:

              • 思想的轉變。首先要徹底地理解什麼是微服務,要知道它相比單體架構、SOA 架構的不同是什麼、優劣是什麼,具體如何落地等問題。

              • 新技術以及新框架的學習。比如spring boot、docker等。

                一些建議:

                • 通過查閱相關資料,對傳統架構和微服務架構的區別以及演變流程,可以首先有一個概念性的瞭解。

                • 可以先讓一部分人使用微服務架構並且做到深入的程度,然後再在企業中整體推廣。

                篇幅限制,只截取了部分,完整內容可以點擊下方“閱讀原文”查看。


                嘉賓:張鋒,《微服務架構實戰》一書作者,北京航空航天大學軟體工程碩士,資深架構師,有10多年管理和架構經驗,在業界頗具威望和影響力。曾就職於神州資料、亞信科技、中文在線及多家互聯網公司,擔任架構師及技術總監等職位,現在就職於中青旅,任架構組組長,成功管理和指導過三農綜合服務信息平臺、西北企業雲服務平臺、省級電信平臺及多個互聯網平臺的架構升級改造。擁有工信部認證高級信息系統專案管理師資格。


                ●編號767,輸入編號直達本文

                ●輸入m獲取文章目錄

                推薦↓↓↓

                演算法與資料結構

                更多推薦18個技術類公眾微信

                涵蓋:程式人生、演算法與資料結構、黑客技術與網絡安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

赞(0)

分享創造快樂