微服務架構是由Martin Fowler在他這篇microservices博客中提出來的,與之對立的是monolithic架構。html
monolithic架構概念 vs. 微服務架構概念數據庫
monolithic架構指的是應用被以單一單元構建。好比一個小型訂餐網站包含菜品展現、下訂單、在線支付等業務功能模塊,該網站的後端系統應用實現了全部這些業務功能。編程
而微服務架構則是由一組微服務組成的架構模式。每一個微服務都是一個可獨立部署的完整系統。一組微服務組成微服務層(注意這裏的服務層不一樣於monolithic架構中的服務層,那個是單系統中的功能模塊分層)。微服務層上面通常是應用層,應用層經過組合使用微服務層的各個微服務而向外提供接口(好比HTTP API接口)。各個微服務能夠經過RPC接口供應用層調用,好比利用Thrift、Avro。後端
微服務拆分方法安全
微服務架構中的微服務通常按照業務功能來拆分,將關聯性較強的業務拆成一個微服務,好比上面訂餐網站能夠拆分紅用戶服務、訂單服務、菜品服務、支付服務等。具體來講通常根據業務實體名詞如訂單、用戶或者業務動做如登陸、下載等來拆分。架構
數據集成 vs. 服務集成運維
數據集成是一種比較傳統的系統集成方式,其中心是數據。好比交易系統會操做訂單表和用戶表,好比生成訂單。而短信通知系統也會訪問訂單表和用戶表,根據訂單的狀態來發出不一樣的短信通知給用戶:好比給金額較大的訂單對應的用戶發一些促銷活動短信,給一些未完成訂單的用戶發短信提醒其完成訂單。這就是一種數據集成方式,交易系統和短信通知系統依靠訂單表和用戶表進行集成。這種集成方式的優勢在於實現簡單,缺點有下面幾條:編程語言
業務數據庫負擔較大,由於多個系統都訪問同一個數據庫的同幾張表分佈式
安全性,交易系統能夠修改訂單表中的訂單狀態是理所固然的事,但因爲短信通知系統也能夠直接訪問訂單表,可能致使一些意想不到的問題微服務
擴展性問題:交易系統若是之後想把訂單表從RDBMS遷到HBase可能就沒那麼容易了,由於還有不少其餘系統也依賴於訂單表,真可謂牽一髮而動全身;或者各個系統可能擅自作主給表增減字段,都會帶來很差後果
DAO代碼重複,若是交易系統和短信通知系統由兩個不一樣部門的團隊開發,那麼每一個系統中都會有針對訂單表和用戶表的DAO代碼
服務集成則打破了數據集成模式,再也不以數據爲中心集成各系統。微服務架構自然就擁抱服務集成方式。若是用服務集成方式從新設計上面的交易系統和短信通知系統,那麼就會提出兩個微服務:用戶微服務,負責對用戶信息進行管理(具體底層是否真的操做關係數據庫表,外部已經不關心,即外部不知道用戶信息是存在MySQL、Redis仍是兩者都有,也不須要知道);和訂單微服務,負責對訂單信息進行管理。交易系統和短信通知系統都被提取到更上一層的應用層,他們分別調用用戶微服務和訂單微服務完成任務。這樣用戶數據狀態的變化和訂單數據狀態的變化將再也不同時受控於交易系統和短信通知系統,而只由用戶微服務和訂單微服務控制。
微服務與微服務之間相互調用
通常避免微服務直接調用另一個微服務,尤爲忌諱兩個微服務相互調用,若是存在兩個微服務相互調用的場景,那麼得慎重衡量下微服務拆分是否合理。
固然某些狀況沒法避免微服務之間相互調用,這時候咱們通常能夠採用兩種方式實現:
消息隊列
消息總線
monolithic架構與微服務架構各自優缺點
除了上面提到的一些優缺點外。下面再總結下兩種架構的各自優缺點。
首先看monolithic架構,它的優勢是:部署方便,只須要部署一份代碼。但它的缺點有不少:
代碼龐雜,理解困難,新人上手也困難
維護困難,通常一個monolithic架構應用得由一個團隊維護,若是應用越大,則維護的人越多,團隊管理成本也越高,團隊效率也會越低下(3-5人是最佳團隊規模)
啓動通常較慢
持續部署困難:每一次小改動都須要從新部署整個應用
技術堆棧固化:嘗試新技術的代價過高
擴展困難:應用某些部分偏IO密集型、某些部分卻偏CPU密集型,但應用卻只部署在一臺機器上,很難用單一硬件來知足應用各部分對硬件資源的不一樣要求
微服務架構的優勢天然與上面的缺點相反,列舉三條:
每一個微服務功能簡單,代碼量也很少,新人上手容易
每一個微服務能夠由不一樣團隊開發,每一個微服務通常由1-3人開發維護
系統穩定性加強,單個服務的失效不會影響其餘服務,能夠必定程度實現服務降級
容易嘗試技術創新,甚至每一個微服務均可以採用不一樣的編程語言編寫,只要對外提供約定好的接口就行
但微服務架構也有缺點,按照我我的理解的嚴重程度由高到低排列以下:
運維成本高:原來一個應用一個進程,如今被拆分紅微服務後可能有十幾個進程,而且每一個微服務都須要獨立部署
測試成本高:微服務架構帶來的是一個分佈式系統,分佈式系統的測試比單系統測試更復雜
微服務升級帶來的接口不向後兼容問題
每一個微服務開發者都須要關注微服務開發、集成、測試、部署、上線完整流程
爲了應對微服務升級帶來的接口不向後兼容問題,通常能夠對接口升級作一些約定以保證接口向後兼容,假設微服務採用Thrift接口開放給應用層,那麼約定以下:
通常接口升級只容許下面幾種狀況(這種狀況可以保證Thrift服務端二進制代碼向後兼容客戶端, 即Thrift服務端由V1.0.9升級到V1.1.0,客戶端依然可使用V1.0.9 Thrift服務端對應的Stub 代碼): > 增長新接口方法或者新結構體(Struct) > 在接口方法參數後面增長非必須參數 > 爲結構體(Struct)增長非必須參數 > 修改返回值類型爲void的接口方法,使其返回值類型爲任意其餘類型 > 刪除接口方法簽名中的throw > 從結構體中刪除field > 重命名結構體 > 修改命名空間 不容許的狀況包括: > 刪除或者重命名接口方法 > 修改非void返回值類型接口方法的返回值類型 > 修改接口方法參數類型 > 爲非void返回值類型接口方法添加throw > 經過Thrift接口開放給外部的系統在升級後必須升級pom.xml中的版本號,同時對應的inf接口 項目的版本號也要跟着升級