近幾年,微服務成爲最流行的技術名詞之一,尤爲受到亞馬遜、阿里等電商巨頭的影響,不少傳統企業在實施電商過程當中也紛紛往微服務架構靠攏,相比單體架構,微服務確實有不少優勢,就像 Sam Newman 在「Building Microservices」[1] 中所闡述的那樣:html
技術異構性程序員
彈性數據庫
伸縮性編程
容易部署設計模式
…服務器
可是計算機科學做爲一門平衡的科學,任何技術架構在帶來收益的同時也會有其侷限性,做爲系統架構師或者決策人員,必定要對此有清醒的認識。本文將重點闡述成功實施微服務的先決條件,所面臨的主要挑戰和風險,傳統企業在實施電商過程當中的決策要素以及正確的實施策略。BTW,做者本人對微服務沒有任何成見,我在 amazon 工做期間一直接觸的就是微服務架構,並且本人也是 Adrian Cockcroft 的超級粉絲。因此各位微服務控們千萬不要拍磚。架構
通常而言,成功實施微服務的先決條件包括:併發
匹配的組織架構框架
實力雄厚的技術團隊(包括開發 / 測試 / 運維)運維
清晰的業務邊界
其中第一條換個洋氣點的說法就是康維定律(Conway’s Law[2]),這是我最喜歡的定律之一,現實中接觸到的各個案例無一例外:
"organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations."
康維定律簡單來講,就是任何軟件都反映出製造它的團隊的組織結構,這是由於人們會以反映他們組織形式的方式工做。 換句話說,採用微服務架構的組織結構也應該是分散的。看看現實中成功實施微服務的那些公司:Amazon、Netflix、阿里那個不是分散的組織結構。
至於後面兩條的緣由我將在下面一節深刻探討。
更長的學習曲線
主要包括:
除了須要瞭解業務邏輯外,也須要花大量精力去學習底層微服務框架提供的各類服務並聽從其契約,如下圖爲例,爲了實施一個基於微服務架構的電商,技術團隊須要掌握如下:
業務邏輯及其之間的接口
基於容器的部署和工具,好比 Docker、Kubernetes 等
微服務框架自己的學習,包括 API 網關、服務發現和註冊機制、熔斷、分佈式配置等等
甚至背後的理論 / 設計模式,諸如 CAP、BASE 等等
更多的開發 / 測試工做
例如:
由於常見微服務架構都是每一個服務擁有本身的數據庫,致使須要跨表實現統計報表等功能將變得很複雜
對於哪些須要依賴其餘微服務的微服務開發及測試,你不得不在本地也安裝全部須要依賴的微服務,即便採用 Docker 容器,根本問題並無改變,與單體服務的開發相比較而言,開發測試變得很繁瑣
代碼自己也要聽從微服務框架的各類契約,例如一個使用 Hystrix 熔斷機制的代碼以下:
@Service
public class MyService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "errorHandler")
public String myService(String name) {
return restTemplate.getForObject("http://MYSERVICE/myservie?name="+name,String.class);
}
public String errorHandler(String name) {
return "There is an error for service "+name;
}
}複製代碼
重構的代價
因爲各類緣由(特別是在對業務的理解不夠或者業務變更頻繁的狀況下),已經上線的微服務發現並不合適從而須要重構,例如須要把計價服務從新合併回產品服務,至少遵循如下步驟(請參考下圖):
首先在產品數據庫中創建與計價有關的表,創建導入工具吧計價數據庫中的數據導入到產品數據庫中,須要注意的是,若是產品服務和計價服務採用不一樣的數據庫,還須要額外的開發成本編寫導入工具。在本步驟完成後,產品服務並不提供任何計價功能,只是全部計價服務中的數據會被不斷(同步或異步)導入到產品數據庫中。
在產品服務中引入計價功能並暴露相應接口,在充分測試後配置 API 網關(如 Zuul 或者 Istio)對計價功能調用進行分流,期間全部流入老的計價數據庫的數據依然會被導入到產品數據庫中。
通過一段時間的金絲雀發佈後,最終全部的計價功能調用都進入產品 / 計價服務,老的計價服務和相應的數據庫被卸載。
固然這是在很是理想的狀況下,現實狀況比這個複雜的多,例如部分須要合併部分須要拆分,採用不一樣的編程語言,採用不一樣的數據庫技術,其它微服務對相關微服務的依賴等等。另外典型的微服務架構中不一樣的微服務由不一樣的組 / 部門去維護,相關的溝通協做也是一個不容忽視的成本,因此在業務不穩定或者理解不充分的狀況下貿然實施微服務的代價是很是巨大的!
微服務架構比單體服務更容易發生問題,不可是由於分佈式計算自己複雜性帶來的各類問題(如一致性問題),並且各類流行的微服務框架都有這樣那樣的坑,以電商業務爲例,用戶 1 須要上架一批新產品,爲了提升併發性以及下降服務之間的耦合度,當前的微服務架構採用消息總線去通知計價服務 / 倉庫服務 / 產品服務進行相應處理,不幸的是,因爲消息的異步性,極可能對於某個產品而言,產品服務最後被通知到,期間若是用戶 2 查詢到了對應的庫存但卻發現相關的產品不存在(以下圖所示),這顯然違反了因果一致性(casual consistency)!
想象一下訂單服務的實現須要調用倉庫服務,計價服務,支付服務等多個服務,中間任何一個環節出錯都將致使訂單處理失敗,有時爲了提升處理的併發量,每每採用基於消息總線的異步方式,這樣想作到快速定位到錯誤根源對開發人員是一個不小的挑戰,通常而言,咱們不得不從兩個方面入手:
應用級別的關聯,全部異步調用都必須引入消息標識關聯
藉助於微服務框架的分佈式追蹤機制,日誌聚合等功能(如 zipkin,CloudWatch 等)
即使這樣,出錯調試的困難度和須要的時間也和單體服務不是一個量級的,並且大部分狀況下,在單體服務中很容易重現並在本地經過單步跟蹤快速解決的問題,對於微服務而言就變得不那麼容易了。
在不少介紹微服務架構優勢的文章中,常見的一條就是「易於部署」,實際上之因此「易於部署」,是拿單個「微服務「和單體服務相比較而言的,可是部署構成企業業務的幾十個甚至上百個微服務的整體複雜度絕對比單體服務大的多,這就是爲何全部基於微服務架構的應用都必須依賴自動化的部署能力,這對體術團隊提出了兩方面要求:
掌握自動化運維工具(如 Ansible)和相關的設計模式 (如服務器提供模式、服務器模版管理模式、基礎架構定義模式等 [3])
微服務自己是快速部署匹配的,若是不是則須要進行重構 [4]。
從業務角度咱們必須思考如下這些問題:
你的業務體量到底有多大,會不會成長爲相似於 / 接近於 Amazon/Netflix/Google/ 阿里 / 騰訊這些巨頭體量的下一個巨頭?
若是會,那麼多長時間,幾年仍是幾十年?
實施電商後的產品升級 / 運維 / 擴展誰來作,可否提供足夠的技術實力來應付微服務框架中的各類潛在風險
對業務的理解是否很是深入,仍是隻停留在初級階段?
公司組織結構是否有利於實施微服務架構?
是否有其餘更爲簡單的解決方案
總之,做爲系統架構師或者決策人員,咱們要作的就是透過「絢麗包裝」的外表理解各類技術架構的本質從而避免過分設計給企業帶來巨大的風險,在這點上 Jeff Dean 在其穩重「challenges in building large-scale information retrieval systems」中的經典名言值得咱們借鑑 [5]:
Design for ~10*growth, plan to rewrite before ~100*
Martin Fowler 在其「MonolithFirst」一文 [5] 中明確指出:
幾乎全部成功的微服務案例所有來源於業務足夠複雜的單體服務
幾乎全部不成功的微服務案例都是直接從頭開發
實際上做爲傳統行業實施電商一個穩妥的方案是從單體開始,隨着業務變得愈來愈複雜逐步慢慢演進到微服務,具體來講:
單體服務的實施中須要採用良好的編程習慣,使得整個系統模塊化並且業務邊界清晰,若是一開始對業務不太熟悉,這須要不斷的重構。
單體服務自己應該儘可能遵循雲部署的那些基本原則,諸如無狀態、經過環境變量注入配置信息等 [4]。
在電商業務變得足夠複雜的狀況下,逐步對有關服務進行拆分,須要注意的是此處只是邏輯上的拆分
增強對自動化運維能力的建設。
最終隨着企業組織結構的逐步調整過渡到微服務架構。
微服務的出現給傳統企業實施電商業提供了強大 / 靈活 / 敏捷的框架,但同時也對不管技術仍是業務上都提出了更高 / 更嚴格的要求,不重視這些潛在風險將帶來巨大風險,因此微服務不是企業電商解決方案的銀彈,一般只有採起更爲務實嚴謹的演進路線才能實現咱們的目標。
我大概在 2006 年開始參與架構設計,原覺得學習架構就像學習編程語言同樣,先了解基本的語法,再研究細節和原理,而後實踐一下就可以快速掌握。 但真正深刻後才發現,架構設計的難度和複雜度要高不少。
從最先開始接觸架構設計,到自我感受完全掌握架構設計的精髓,我至少花費了 8 年的時間。 我曾經覺得是本身天資愚笨纔會這樣,後來我帶了團隊,看到幾乎每一個程序員在嘗試架構設計的時候,都面臨着我曾經遇到過的各類困惑和瓶頸。
今天,我想把我過去全部的經驗都分享在裙69-75-79-75-1裏,裏面都是我精心錄製成視頻供你們免費下載,但願能幫你快速成爲一名架構師。
參考資料
Building Microservices: Designing Fine-Grained Systems, Publisher: O'Reilly Media; 1 edition (February 20, 2015)
https://en.wikipedia.org/wiki/Conway%27s_law
Infrastructure as Code: Managing Servers in the Cloud, Publisher: O'Reilly Media; 1 edition (June 27, 2016)
https://12factor.net
https://static.googleusercontent.com/media/research.google.com/en//people/jeff/WSDM09-keynote.pdf
https://martinfowler.com/bliki/MonolithFirst.html