近來,幾乎人人都在談論微服務。開發人員都在研究Eric Evan的著做《領域驅動設計》。團隊正在重構一體化應用,尋找限界上下文,並定義通用語言。雖然有不可勝數的文章、視頻和座談能夠幫助您轉換到微服務,但不多有人願意多花些時間來探討一下某個具體的應用是否應該採用微服務。數據庫
使用微服務架構有不少充分的理由,但天下沒有免費的午飯。微服務雖有諸多優點,但也增長了複雜性。團隊應該積極應對這種複雜性,但前提是應用可以受益於微服務。緩存
切忌盲目跟風,請負責任地考慮是否採用微服務架構性能優化
Matt Stine和我在最近與一家客戶一塊兒研究了他們的一些應用。咱們的討論以「一切都應該是微服務」爲出發點,由於這在現在已經「司空見慣」。結果談話陷入了僵局,你們就各類實施細節爭論不休。架構
Matt在白板上寫下了一組原則。這些簡單的句子在這一天剩下的時間裏指導着咱們,咱們審視應用架構的每一個部分,尋找微服務能夠交付價值的地方。這個列表完全改變了對話的氛圍,幫助團隊制定了明智的架構決策。併發
爲了避免濫用微服務,咱們列出了這組原則,幫助您集中精力開展工做。經過閱讀下面的這些原則,看看特定的應用可否因某一個原則而受益。若是對於如下一個或多個原則,您的回答是「是」,那麼這個功能就適合採用微服務。若是對於每一個原則,您的回答都是「否」,那麼您可能會給系統引入偶發複雜性。運維
01分佈式
多個變動速度微服務
系統的各個部分是否是須要以不一樣的速度或向不一樣的方向發展?若是是,就分別採用微服務吧。這讓每一個組件都有了獨立的生命週期。高併發
在任何系統中都是一些模塊不多受影響,而另外一些模塊彷佛每次迭代都會發生變化。咱們來舉例說明,假設有一款用於在線零售的一體化電子商務應用。源碼分析
在平常開發工做中,購物車(Cart)和庫存(Inventory)功能基本上不會受影響。但咱們可能會不斷地試驗推薦引擎(Recommendation Engine)。咱們還想努力提升搜索(Search)能力。若是將這兩個模塊分別放入微服務中,它們的團隊就能以更快的速度進行迭代,從而讓咱們快速交付業務價值。
02
獨立的生命週期
若是一個模塊須要有徹底獨立的生命週期(是指代碼提交到生產的流程),那麼它應該採用微服務。它應該有本身的代碼存儲庫、CI/CD pipeline等。
範圍越小,測試微服務就越容易。我記得之前遇到過一個項目,它的迴歸測試套件須要80個小時!不用說,咱們並無常常執行完整的迴歸測試(雖然咱們真的想這麼作)。微服務方法支持精細的迴歸測試。這爲咱們節省了大量的時間。咱們可以及早發現問題。
測試不是咱們採用微服務的惟一理由。在一些狀況下,業務需求可能促使咱們採用微服務架構。讓咱們以Widget.io一體化應用爲例。
企業領導可能發現了新商機,而上市速度相當重要。若是咱們決定向一體化應用添加必要的新功能,可能要花很長時間。咱們的行動速度沒法達到企業的要求。
但做爲獨立的微服務,「項目X」(以下所示)能夠有本身的部署流水線。這個方法使咱們可以迅速迭代,重新的業務商機中獲利。
03
獨立的可擴展性
若是系統各部分的負載或吞吐量特徵不一樣,它們的擴展需求可能也不一樣。解決方案就是把這些組件放入獨立的微服務中!這樣一來,服務可以以不一樣的速度擴展。
即便粗略地看一下通常的架構,咱們也會發現不一樣模塊具備不一樣的擴展要求。咱們從這個角度看一下Widget.io一體化應用。
最有可能的狀況是,其中的賬戶管理(Account Administration)功能並不須要承受訂單處理(Order Processing)系統承受的那麼多壓力。過去,咱們必須擴展整個一體化應用來支持最不穩定組件。這種方法會致使基礎架構成本增長,由於咱們不得不在應用的某個部分出現最壞狀況時「過分調配」。
若是將訂單處理(Order Processing)功能重構爲微服務,咱們能夠根據須要擴展和收縮。結果就如這張圖所示:
04
隔離故障
有時,咱們但願將應用與特定類型的故障隔離開來。例如,當咱們依賴一項外部服務但這個服務沒法知足咱們的可用性目標時,該怎麼辦?咱們能夠建立微服務,將這種依賴關係與系統的其他部分隔離。以後,咱們能夠在該服務中構建合適的故障轉移機制。
在這裏順便給你們推薦一個架構交流羣:617434785,裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化這些成爲架構師必備的知識體系。還能領取免費的學習資源。相信對於已經工做和遇到技術瓶頸的碼友,在這個羣裏會有你須要的內容。
再來看一看咱們的示例Widget.io一體化應用。庫存(Inventory)功能剛好與一個遺留的數據倉庫系統交互,然後者的正常運行時間不夠好。若是將庫存(Inventory)模塊重構到微服務中,咱們就能夠在可用性方面實現服務級別目標。咱們可能須要增長賬戶冗餘以應對脆弱的數據倉庫系統。咱們還能夠引入一些最終一致性機制,好比Redis中的緩存清單。但如今,轉型到微服務減輕了因爲不可靠的第三方依賴關係而致使的性能不佳。
05
簡化與外部依賴關係的交互
這個原則與「Isolated Failure」相似。換一種說法是:咱們更專一於保護系統免受頻繁變化的外部依賴關係的影響。(這也多是供應商依賴關係,即把一個服務提供商換成另外一個,好比更換負責付款處理的供應商)。
微服務至關於一個間接的層,把您與第三方依賴關係隔離。咱們能夠在覈心應用與依賴關係之間部署一個由咱們控制的抽象層,而不是直接調用依賴關係。此外,咱們能夠構建這個抽象層,讓應用更便於使用,由於隱藏了依賴關係的複雜性。若是將來發生變動,必須進行遷移,那麼變動將只限於「外觀」,不須要更大規模的重構。
06
根據工做自由選擇合適的技術
利用微服務,團隊能夠自由使用本身喜歡的技術堆棧。在某些狀況下,一項業務要求剛好適合一項特定的技術選型。而其餘時候,技術選型由開發人員的偏好和熟悉程度決定。
注意:這個原則並非說能夠隨意使用任意技術!請向團隊提供關於技術選型的指導。過多的分散堆棧會在認知上增長開銷,比基於「一刀切」模型實現標準化更糟糕。爲一個堆棧及時更新第三方存儲庫就已經頗有挑戰性了,更況且是將這種費力工做擴大四倍或五倍,會大大增長公司的負擔。請採起有效措施,關注那些您知道如何提供支持的「妥善方法」。
在Widget.io這個例子中,與其他模塊相比,搜索(Search)功能可能會受益於不一樣的語言或數據庫選擇。若是須要,這麼作很是簡單。固然,出於其餘緣由,咱們已經對它進行了重構!
文化
上面都是技術討論。那麼在文化上呢?
沒有任何技術決策是憑空想出來的。所以,在深刻了解精彩的微服務世界以前,先了解一下您的企業。您的組織結構是否能輕鬆支持微服務架構?根據康威定律,您的成功機率如何?
「通過深思熟慮的早期經驗教訓可能會抵消康威定律的效果。」
——- @jmckenty
Mel Conway在50年前總結說,任何企業設計的系統都會反映該企業的組織結構。換句話說,若是團隊的組織結構不是小型自主團隊,那麼工程師不可能創造出由小型自主服務組成的軟件。這種認識促成了反向康威操縱,即鼓勵團隊改變其組織結構,來反映他們渴望在應用中看到的架構。
您還應該考慮文化是否準備就緒。微服務提倡以小批量方式頻繁進行更改,這種頻率通常與傳統的季度發佈週期相沖突。利用微服務,您不會遇到代碼凍結或「一窩蜂式」的代碼集成。雖然基於微服務的架構確定能在傳統的瀑布式環境中運行,但您沒法發揮它的所有優點。
還要考慮如何調配基礎架構。關注自助服務和優化價值流的團隊通常都採用微服務模式。Pivotal Cloud Foundry等平臺幫助團隊在幾分鐘內(而不是幾周或幾個月)快速部署、測試和優化服務。開發人員只需按一下按鈕便可啓動實例,這種作法可以推進實驗和學習。Buildpack能夠自動執行依賴關係管理。這意味着開發人員和運維人員能夠專一於交付業務價值。
即便是你所在行業中的公司也能夠從每一年部署四次轉型到一個月部署上千次。
最後,咱們針對應用問兩個具體問題:
這款應用是否有多個業務全部人?若是系統有多個獨立的自主業務全部人,則會有兩種不一樣變動來源。這種狀況可能會致使衝突。利用微服務,您能夠實現「獨立的生命週期」,讓不一樣的支持者滿意。
這款應用是否由多個團隊全部?多個團隊開發一個系統的「協調成本」可能很高。所以請爲他們定義API。以後,每一個團隊均可以使用Spring Cloud Contract構建獨立的微服務,也可使用Pact進行消費者驅動的合同
測試。
對於這些問題,若是您有任一項回答是「是」,那麼您就應該使用微服務解決方案。
總結
微服務之路的想法是好的。但有很多團隊在沒有分析需求的狀況下就踏上了微服務的浪潮。微服務很是強大,你們都想用!但必定要作出權衡取捨。並且必需要了解應用的業務推進因素,這是無可替代的,由於這對肯定合適的架構方法相當重要。