Java高級架構:微服務架構的核心概念
我們先看相同點:
- 需要Registry,實現動態的服務註冊發現機制;
- 需要考慮分布式下面的事務一致性,CAP原則下,兩段式提交不能保證性能,事務補償機制需要考慮;
- 同步調用還是異步消息傳遞,如何保證消息可靠性?SOA由ESB來集成所有的消息;
- 都需要統一的Gateway來匯聚、編排接口,實現統一認證機制,對外提供APP使用的RESTful接口;
- 同樣的要關註如何再分布式下定位系統問題,如何做日誌跟蹤,就像我們電信領域做了十幾年的信令跟蹤的功能;
不相同點:
- 是持續集成、持續部署?對於CI、CD(持續集成、持續部署),這本身和敏捷、DevOps是交織在一起的,我認為這更傾向於軟件工程的領域而不是微服務技術本身;
- 使用不同的通訊協議是不是區別?微服務的標桿通訊協議是RESTful,而傳統的SOA一般是SOAP,不過目前來說采用輕量級的RPC框架Dubbo、Thrift、gRPC非常多,在Spring Cloud中也有Feign框架將標準RESTful轉為代碼的API這種仿RPC的行為,這些通訊協議不應該是區分微服務架構和SOA的核心差別;
- 是流行的基於容器框架還是虛擬機為主?Docker和虛擬機還是物理機都是架構實現的一種方式,不是核心區別;
微服務架構的精髓在切分
服務的切分上有比較大的區別,SOA原本是以一種“集成”技術出現的,很多技術方案是將原有企業內部服務封裝為一個獨立進程,這樣新的業務開發就可重用這些服務,這些服務很可能是類似供應鏈、CRM這樣的非常大的顆粒;而微服務這個“微”,就說明了他在切分上有講究,不妥協。無數的案例證明,如果你的切分是錯誤的,那麽你得不到微服務承諾的“低耦合、升級不影響、可靠性高”之類的優勢,而會比使用Monolithic有更多的麻煩。
不拆分存儲的微服務是偽服務:在實踐中,我們常常見到一種架構,後端存儲是全部和在一個數據庫中,僅僅把前端的業務邏輯拆分到不同的服務進程中,本質上和一個Monolithic一樣,只是把模塊之間的進程內調用改為進程間調用,這種切分不可取,違反了分布式第一原則,模塊耦合沒有解決,性能卻受到了影響。
分布式設計第一原則 — “不要分布你的對象”
微服務的“Micro”這個詞並不是越小越好,而是相對SOA那種粗粒度的服務,我們需要更小更合適的粒度,這種Micro不是無限制的小。
如果我們將兩路(同步)通信與小/微服務結合使用,並根據比如“1個類=1個服務”的原則,那麽我們實際上回到了使用Corba、J2EE和分布式對象的20世紀90年代。遺憾的是,新生代的開發人員沒有使用分布式對象的經驗,因此也就沒有認識到這個主意多麽糟糕,他們正試圖重復歷史,只是這次使用了新技術,比如用HTTP取代了RMI或IIOP。
微服務和Domain Driven Design
一個簡單的圖書管理系統肯定無需微服務架構。既然采用了微服務架構,那麽面對的問題空間必然是比較宏大,比如整個電商、CRM。
如何拆解服務呢?
使用什麽樣的方法拆解服務?業界流行1個類=1個服務、1個方法=1個服務、2 Pizza團隊、2周能重寫完成等方法,但是這些都缺乏實施基礎。我們必須從一些軟件設計方法中尋找,面向對象和設計模式適用的問題空間是一個模塊,而函數式編程的理念更多的是在代碼層面的微觀上起作用。
Eric Evans 的《領域驅動設計》這本書對微服務架構有很大借鑒意義,這本書提出了一個能將一個大問題空間拆解分為領域和實體之間的關系和行為的技術。目前來說,這是一個最合理的解決拆分問題的方案,透過限界上下文(Bounded Context,下文簡稱為BC)這個概念,我們能將實現細節封裝起來,讓BC都能夠實現SRP(單一職責)原則。而每個微服務正是BC在實際世界的物理映射,符合BC思路的微服務互相獨立松耦合。
微服務架構是一件好事,逼著大家關註設計軟件的合理性,如果原來在Monolithic中領域分析、面向對象設計做不好,換微服務會把這個問題成倍的放大
以電商中的訂單和商品兩個領域舉例,按照DDD拆解,他們應該是兩個獨立的限界上下文,但是訂單中肯定是包含商品的,如果貿然拆為兩個BC,查詢、調用關系就耦合在一起了,甚至有了麻煩的分布式事務的問題,這個關聯如何拆解?BC理論認為在不同的BC中,即使是一個術語,他的關註點也不一樣,在商品BC中,關註的是屬性、規格、詳情等等(實際上商品BC這個領域有價格、庫存、促銷等等,把他作為單獨一個BC也是不合理的,這裏為了簡化例子,大家先認為商品BC就是商品基礎信息), 而在訂單BC中更關註商品的庫存、價格。所以在實際編碼設計中,訂單服務往往將關註的商品名稱、價格等等屬性冗余在訂單中,這個設計解脫了和商品BC的強關聯,兩個BC可以獨立提供服務,獨立數據存儲
小結
微服務架構首先要關註的不是RPC/ServiceDiscovery/Circuit Breaker這些概念,也不是Eureka/Docker/SpringCloud/Zipkin這些技術框架,而是服務的邊界、職責劃分,劃分錯誤就會陷入大量的服務間的相互調用和分布式事務中,這種情況微服務帶來的不是便利而是麻煩。
【文章福利】
小編推薦一個Java交流群:937053620,群內提供設計模式、spring/mybatis源碼分析、高並發與分布式、微服務、性能優化,面試題整理合集等免費資料!
Java高級架構:微服務架構的核心概念