微服務架構實踐總結
微服務架構是由Martin Fowler在他這篇microservices博客中提出來的,與之對立的是monolithic架構。
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接口 項目的版本號也要跟著升級
全文完,轉載請注明出處http://my.oschina.net/feichexia/blog/344190,謝謝!