天天看點

微服務

什麼是微服務架構 

        “微服務”一詞源于Martin Fowler的名為Microservices的博文, 可以在他的官方部落格 上找到: http://mar巨nfowler.com/articles/microservices.html。

         簡單地說, 微服務是系統架構上的一種設計風格, 它的主旨是将一個原本獨立的系統 拆分成多個小型服務,這些小型服務都在各自獨立的程序中運作,服務之間通過基于HTTP 的RESTful API進行通信協作。 被拆分成的每一個小型服務都圍繞着系統中的某一項或一 些耦合度較高的業務功能進行建構, 并且每個服務都維護着自身的資料存儲、 業務開發、 自動化測試案例以及獨立部署機制。 由千有了輕量級的通信協作基礎, 是以這些微服務可 以使用不同的語言來編寫。

與單體系統的差別

        在以往傳統的企業系統架構中, 我們針對一個複雜的業務需求通常使用對象或業務類 型來建構一個單體項目。 在項目中我們通常将需求分為三個主要部分: 資料庫、 服務端處 理、 前端展現。 在業務發展初期, 由于所有的業務邏輯在一個應用中, 開發、 測試、 部署 都還比較容易且友善。 但是, 随着企業的發展, 系統為了應對不同的業務需求會不斷為該 單體項目增加不同的業務子產品; 同時随着移動端裝置的進步, 前端展現子產品已經不僅僅局 限于Web的形式,這對千系統後端向前端的支援需要更多的接口子產品。 單體應用由千面對 的業務需求更為寬泛, 不斷擴大的需求會使得單體應用變得越來越腕腫。 單體應用的問題就逐漸凸顯出來, 由于單體系統部署在一個程序内, 往往我們修改了一個很小的功能, 為 了部署上線會影響其他功能的運作。

        并且, 單體應用中的這些功能子產品的使用場景、 并發 量、 消耗的資源類型都各有不同, 對于資源的利用又互相影響, 這樣使得我們對各個業務 子產品的系統容量很難給出較為準确的評估。 是以, 單體系統在初期雖然可以非常友善地進 行開發和使用, 但是随着系統的發展, 維護成本會變得越來越大, 且難以控制。 為了解決單體系統變得龐大脯腫之後産生的難以維護的問題,微服務架構誕生了并被 大家所關注。 我們将系統中的不同功能子產品拆分成多個不同的服務, 這些服務都能夠獨立 部署和擴充。 由于每個服務都運作在自己的程序内, 在部署上有穩固的邊界, 這樣每個服 務的更新都不會影響其他服務的運作。 同時, 由千是獨立部署的, 我們可以更準确地為每 個服務評估性能容量, 通過配合服務間的協作流程也可以更容易地發現系統的瓶頸位置, 以及給出較為準确的系統級性能容量評估。

如何實施微服務 

       在實施微服務之前, 我們必須要知道, 微服務雖然有非常多吸引人的優點, 但是也因 為服務的拆分引發了諸多原本在單體應用中沒有的問題。

             • 運維的新挑戰:在微服務架構中, 運維人員需要維護的程序數量會大大增加。 有條 不紊地将這些程序編排群組織起來不是一件容易的事, 傳統的運維人員往往很難适 應這樣的改變。 我們需要運維人員有更多的技能來應對這樣的挑戰, 運維過程需要 更多的自動化, 這就要求運維人員具備一定的開發能力來編排運維過程并讓它們能 自動運作起來。

             • 接口的一緻性:雖然我們拆分了服務, 但是業務邏輯上的依賴并不會消除, 隻是從 單體應用中的代碼依賴變為了服務間的通信依賴。 而當我們對原有接口進行了一些 修改, 那麼互動方也需要協調這樣的改變來進行釋出, 以保證接口的正确調用。 我 們需要更完善的接口和版本管理, 或是嚴格地遵循開閉原則。

             • 分布式的複雜性:由于拆分後的各個微服務都是獨立部署并運作在各自的程序内, 它們隻能通過通信來進行協作, 是以分布式環境的問題都将是微服務架構系統設計 時需要考慮的重要因素, 比如網絡延遲、 分布式事務、 異步消息等。 盡管微服務架構有很多缺點和問題, 但是其實作的靈活開發和自動化部署等優點依然 被廣大優秀架構師和開發者所青眯, 是以解決這些問題就是這幾年諸多架構大師努力的目 标。 在架構師對于一個大型系統架構的設計與實施的過程中, 面對環境、 資源、 團隊等各 種因素的影響, 幾乎不會出現完全相同的架構設計。 對于微服務架構而言更是如此, 由并沒有一個标準或正式的定義,每位架構師都根據自身了解與實際情況來進行設計,并在 發展的過程中不斷演化與完善。 經過多年的發展,MartinFowler在Microservices 一文中, 提煉出了微服務架構的九大特性,用于指導大家設計架構。 

服務元件化 

       元件,是一個可以獨立更換和更新的單元。 就像 PC 中的 CPU、記憶體、 顯示卡、 硬碟一 樣,獨立且可以更換更新而不影響其他單元。 在微服務架構中,需要我們對服務進行元件化分解。 服務,是一種程序外的元件,它 通過 HTTP 等通信協定進行協作,而不是像傳統元件那樣以嵌入的方式協同工作。 每一個 服務都獨立開發、 部署,可以有效避免一個服務的修改引起整個系統的重新部署。 打一個不恰當的比喻,如果我們的 PC 元件以服務的方式建構,那麼隻維護主機闆和一 些必要外設之後,計算能力通過一組外部服務實作,我們隻需要告訴 PC 從哪個位址來獲 得計算能力,通過服務定義的計算接口來實作我們使用過程中的計算需求,進而實作 CPU 元件的服務化。 這樣原本複雜的 PC 服務得到了輕量化的實作,我們甚至隻需要更換服務 位址就能更新PC 的計算能力。 

按業務組織團隊 

       當決定如何劃分微服務時,通常也意味着我們要開始對團隊進行重新規劃與組織。 按 以往的方式,我們往往會從技術的層面将團隊劃分為多個,比如DBA團隊、運維團隊、後 端團隊、 前端團隊、 設計師團隊等。 若我們繼續按這種方式組織團隊來實施微服務架構開 發,當有一個服務出現問題需要更改時,可能是一個非常簡單的變動,比如對人物描述增 加一個字段,這需要從資料存儲開始考慮一直到設計和前端, 雖然大家的修改都非常小, 但這會引起跨團隊的時間耗費和預算審批。

        在實施微服務架構時,需要采用不同的團隊分割方法。 由于每一個微服務都是針對特 定業務的寬棧或是全棧實作,既要負責資料的持久化存儲, 又要負責使用者的接口定義等各 種跨專業領域的職能。 是以,面對大型項目的時候,對于微服務團隊的拆分更加建議按業 務線的方式進行拆分, 一方面可以有效減少服務内部修改所産生的内耗; 另一方面,團隊 邊界可以變得更為清晰。 

做 “産品” 的态度

       在實施微服務架構的團隊中,每個小團隊都應該以做産品的方式,對其産品的整個生 命周期負責。 而不是以項目的模式,以完成開發與傳遞并将成果交接給維護者為最終目标。

       開發團隊通過了解服務在具體生産環境中的情況, 可以增加他們對具體業務的了解, 比如, 很多時候, 一些業務中發生的特殊或異常情況, 很可能産品經理都并不知曉, 但細 心的開發者很容易通過生産環境發現這些特殊的潛在問題或需求。 是以, 我們需要用做 “産品” 的态度來對待每一個微服務, 持續關注服務的運作情況, 并不斷分析以幫助使用者來改善業務功能。 

       智能端點與啞管道

       在單體應用中, 元件間直接通過函數調用的方式進行互動協作。 而在微服務架構中, 由于服務不在一個程序中, 元件間的通信模式發生了改變, 若僅僅将原本在程序内的方法 調用改成RPC方式的調用, 會導緻微服務之間産生煩瑣的通信, 使得系統表現更為糟糕, 是以, 我們需要更粗粒度的通信協定。 在微服務架構中, 通常會使用以下兩種服務調用方式:

            • 第一種, 使用 HTTP的 RESTful API或輕量級的消息發送協定, 實作資訊傳遞與服 務調用的觸發。

            • 第二種, 通過在輕量級消息總線上傳遞消息, 類似 RabbitMQ 等一些提供可靠異步 交換的中間件。

         在極度強調性能的情況下, 有些團隊會使用二進制的消息發送協定, 例如 protobuf。 即使是這樣, 這些系統仍然會呈現出 “智能瑞點和啞管道” 的特點, 這 是為了在易讀性與高效性之間取得平衡。當然大多數Web 應用或企業系統并不需 要在這兩者間做出選擇, 能夠荻得易讀性已經是一個極大的勝利了。

                                                                                                                                                                                                                         一Martin Fowler 

去中心化治理 (有點像區塊鍊的概念)

       當我們采用集中化的架構治理方案時, 通常在技術平台上都會制定統一的标準, 但是 每一種技術平台都有其短闆, 這會導緻在碰到短闆時, 不得不花費大力氣去解決, 并且可 能因為其底層原因解決得不是很好, 最終成為系統的瓶頸。

         在實施微服務架構時, 通過采用輕量級的契約定義接口, 使得我們對于服務本身的具 體技術平台不再那麼敏感, 這樣整個微服務架構系統中的各個元件就能針對其不同的業務 特點選擇不同的技術平台, 終千不會出現殺雞用牛刀或是殺牛用指甲鉗的尴尬處境了。 

去中心化管理資料 

         我們在實施微服務架構時, 都希望讓每一個服務來管理其自有的資料庫, 這就是資料 管理的去中心化。 在去中心化過程中, 我們除了将原資料庫中的存儲内容拆分到新的同平台的其他資料 庫執行個體中之外(如把原本存儲在MySQL中的表拆分後,存儲到多個不同的MySQL執行個體中), 也可以将一些具有特殊結構或業務特性的資料存儲到一些其他技術的資料庫執行個體中(如把 日志資訊存儲到 MongoDB 中或把使用者登入資訊存儲到 Redis中)。 雖然資料管理的去中心化可以讓資料管理更加細緻化, 通過采用更合适的技術可讓數 據存儲和性能達到最優。 但是, 由于資料存儲于不同的資料庫執行個體中後, 資料一緻性也成 為微服務架構中亟待解決的問題之一。分布式事務本身的實作難度就非常大, 是以在微服 務架構中, 我們更強調在各服務之間進行 “無事務” 的調用, 而對于資料一緻性, 隻要求 資料在最後的處理狀态是一緻的即可;若在過程中發現錯誤, 通過補償機制來進行處理, 使得錯誤資料能夠達到最終的一緻性。 

基礎設施自動化 

         近年來雲計算服務與容器化技術的不斷成熟,運維基礎設施的工作變得越來越容易。 但是, 當我們實施微服務架構時, 資料庫、 應用程式的個頭雖然都變小了, 但是因為拆分 的原因, 數量成倍增長。 這使得運維人員需要關注的内容也成倍增長, 并且操作性任務也 會成倍增長, 這些問題若沒有得到妥善解決, 必将成為運維人員的噩夢。 是以, 在微服務架構中, 務必從一開始就建構起 “待續傳遞” 平台來支撐整個實施過 程, 該平台需要兩大内容, 缺一不可。

              • 自動化測試:每次部署前的強心劑, 盡可能地獲得對正在運作的軟體的信心。

              • 自動化部署:解放煩瑣枯燥的重複操作以及對多環境的配置管理。

容錯設計 

        在單體應用中, 一般不存在單個元件故障而其他部件還在運作的情況, 通常是一挂全 挂。 而在微服務架構中, 由于服務都運作在獨立的程序中, 是以存在部分服務出現故障, 而其他服務正常運作的情況。 比如, 當正常運作的服務B調用到故障服務A時, 因故障服 務A沒有傳回, 線程挂起開始等待, 直到逾時才能釋放, 而此時若觸發服務B調用服務A 的請求來自服務C, 而服務 C頻繁調用服務B 時, 由千其依賴服務A, 大量線程被挂起等 待, 最後導緻服務A也不能正常服務, 這時就會出現故障的荽延。

        是以, 在微服務架構中, 快速檢測出故障源并盡可能地自動恢複服務是必須被設計和考慮的。 通常, 我們都希望在每個服務中實作監控和日志記錄的元件, 比如服務狀态、 斷 路器狀态、 吞吐量、 網絡延遲等關鍵資料的儀表盤等。 

演進式設計 

        通過上面的幾點特征, 我們已經能夠體會到, 要實施一個完美的微服務架構, 需要考 慮的設計與成本并不小, 對千沒有足夠經驗的團隊來說, 甚至要比單體應用付出更多的代 價。

        是以, 在很多情況下, 架構師都會以演進的方式進行系統的建構。 在初期, 以單體系 統的方式來設計和實施, 一方面系統體量初期并不會很大, 建構和維護成本都不高。 另一 方面, 初期的核心業務在後期通常也不會發生巨大的改變。 随着系統的發展或者業務的需 要, 架構師會将一些經常變動或是有一定時間效應的内容進行微服務處理, 并逐漸将原來 在單體系統中多變的子產品逐漸拆分出來, 而穩定不太變化的子產品就形成一個核心微服務存 在于整個架構之中。

為什麼選擇Spring Cloud 

         近幾年很多入對于微服務架構的熱情非常高, 但是回頭看 “微服務” 被提及也有很多 年了。 無數的架構師和開發者在實際項目中實踐該設計理念并為此付出了諸多努力, 同時 也分享了他們在微服務架構中針對不同應用場景出現的各種問題的各種解決方案和開源框 架, 其中也不乏國内網際網路企業的傑出貢獻。

           • 服務治理:阿裡巴巴開源的Dubbo和當當網在其基礎上擴充的DubboX、 Netflix的 Eureka、Apache的Consul等。

           • 分布式配置管理:百度的Disconf、 Netflix的Archaius、360的QConf、SpringCloud 的Config、 淘寶的Diamond等。 • 批量任務:當當網的Elastic-Job、 Linkedln的Azkaban、 SpringCloud的Task等。

           • 服務跟蹤:京東的Hydra、SpringCloud的Sleuth、Twitter的Zipkin等。 .......

       上面列舉了一些在實施微服務架構初期, 就需要被我們考慮進去的問題, 以及針對這 些間題的開源解決方案。 可以看到國内、 國外的技術公司都在貢獻着他們的智慧。 我們搜 索微服務架構的實施方案時會發現, 幾乎大部分的分享主要以理論或是一個粗輪廓架構為 主, 整合了來自不同公司或組織的諸多開源架構, 并加入針對自身業務的一些優化, 是以 找不到一個完全相同的架構方案。

        前面我們介紹了一些關于微服務的理念以及特性, 分析了實施微服務的優點和缺點,而這些缺點通常就是這些架構出現的源頭,大家都是為了解決或彌補業務拆分後所引出的 諸多詞題來設計出這些解決方案。而當我們作為一個新手,準備實施微服務架構時,為了 避免踩前輩們踩過的坑,我們不得不在這些核心問題上做出選擇,而選擇又是如此之多, 這必然會導緻在做技術選型的初期, 需要花費巨大的調研、 分析與實驗精力。

繼續閱讀