前言
隨著這幾年微服務的火爆,在平時的工作或者技術交流中,我們總能聽到哪家公司把自己的項目用微服務重構啦,某位技術大佬在 XX 峰會上分享微服務相關技術經驗獲得大家的一致好評啦,好像微服務已經在我們的工作中無處不在了?
關于這個問題,我想說:是的,微服務的時代已經深入扎根中大公司的開發核心,筆者之前所有在老牌互聯網公司早在 2014 年就致力啟動全面轉向微服務,目前仍然在整合 Service Mesh 與容器部署架構。
但是,雖然微服務已經這么火爆了,但是我發現在不同業務不同場景中探討微服務,很多時候大家聊得并不是同一個東西。事實上,到底什么是微服務,到目前為止業界還沒有一個最能蓋棺定論的定義。從這節課開始,我們就來討論下 “什么是微服務?”。
1. 什么是微服務
在業界中,有兩個人對微服務架構的定義是產生了非常深遠的影響,一個是 Martin Fowler,一個是 Netflix 架構總監 Adrian Cockcroft,Netflix 公司對整個微服務架構的推進起到決定性的作用,相信已經對微服務有過一定接觸的同學對 netflix 不會很陌生,前期的 Zuul,Hystrix,Eureka,Ribbon 等著名開源組件就是由 Netflix 所進行開源。
Martin Fowler 在《Microservices》https://www.martinfowler.com/articles/microservices.html 中有一段對微服務進行了一個核心點的定義
In short, the microservice architectural style [1] is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.
這一小段是《Microservices》最重要的定義片段,微服務是一種架構的風格,在這個風格下勾勒出幾個核心點:
- a suite of small services:一組小的服務;
- running in its own process:獨立的進程;
- communicating with lightweight:輕量級的通訊;
- built around business capabilities:基于業務能力構建;
- independently deployable:獨立部署;
- a bare minimum of centralized management:最小的中心化管理。
1.1 一組小的服務
一組 “小” 的服務,這個小其實是相對而言的,原來的單體服務都是把所有的業務大而全的打包在一個單體結構中,而微服務將這些單體結構進行拆分,形成一個一個獨立的服務,這個小是相對原來大而全的結構而言。
很多同學會糾結 “小” 這個點,那么要多小的程度才為之 “小”,因為這個小并沒有特別和明確的規定,所有這也引申出來現在很多 DDD 領域驅動設計來指引微服務的拆分,基本上一個微服務能讓一個開發人員能獨立的理解,就可以稱為一個微服務,具體有多少行代碼不是關鍵。
1.2 獨立的進程
微服務是運行在獨立的進程當中,例如 Java 程序部署在 Tomcat 的容器中,也可以將 Tomcat 部署在 Docker 容器中,因為容器本身也是一種進程,所以微服務可以以進程的方式去擴展。
使用容器進行部署,使得定義,部署與運行一個微服務變的更加簡單,由于微服務粒度比傳統的 SOA 服務更小,它對 Web 應用服務器的要求也變成更加的輕量級。
1.3 輕量級的通訊
微服務主張使用輕量級去構建通訊機制,我認為是使用基于 HTTP 協議的 API 資源,一般是 RESTful API。不過現在正式投入生產的應用中,微服務之間的通訊絕不止于 RESTful,雖然 HTTP 協議相對來說較為簡單,但它在傳輸的性能和可靠性也存在比較大的局限,特別是 JSON 在序列化也較弱。
所以在微服務內部通訊會使用更多的 RPC 框架,例如 Netty,gRPC,阿里的 dubbo 協議等等,甚至還可以使用消息中間件來完成通訊傳輸。
究竟我們的服務應該選擇 RPC 還是 RESTful,在后面的章節會進行討論。
1.4 基于業務能力構建
文中強調了服務的規劃和劃分,是基于業務進行構建,這一點非常的重要,是業務而非技術驅動微服務的設計,這一個觀點從而也推動了領域驅動設計(DDD)的發展,越來越多的人嘗試將領域驅動設計引入微服務架構的設計中。
例如:在電商的系統中,我們劃分服務更多考慮的是業務,例如:用戶服務,商品服務,訂單服務等等,這個在后面劃分服務的章節將會再進行討論。
1.5 獨立部署
在以往的大型獨體項目中,部署和發布永遠是高懸頭頂的達摩克利斯之劍,某一個模塊的錯誤都可能讓整個系統崩塌。
但是微服務的一個關鍵原則是:每一個服務都是系統的組件,均可以獨立的進行部署,團隊之間是不需要特別的進行協調,當我們開發和部署一個服務時,我們只需要確保測試和部署好一個服務,如果真的把它搞砸了,也不會把整個系統都搞砸。
當然,一個服務掛掉了不會把整個系統都搞砸,還需要建立在一個好的微服務治理上,這個問題我們在后面的章節中也會討論。
1.6 最小的中心化管理
最小的中心化管理,其實也可以稱為 “無集中式管理”, 原來的單體服務需要整個技術團隊都是獨立的架構團隊去進行管理,統一的架構,統一的技術棧,統計的存儲。
而在微服務中得益于服務的拆分,人員的拆分,所以在實施微服務將不再受限于系統的技術棧,無論是開發的語言,數據庫,緩存都是可以進行自由的選擇。從理論上來說,微服務是一種通過網絡協議的跨平臺調用,只要規定好服務的接口和服務的網絡協議,服務本身的技術都是可以自由選擇的。
對每個系統本身來說,是最小的中心化管理,但是,如果從整個微服務的系統架構來說,我們需要考慮到整個微服務的注冊,發現,降級,監控,編排等等,這也衍生了我們對微服務更多的 “管理中心”,例如我們會使用 SpringCloud 或 Dubbo 框架進行管理。
1.7 究竟什么是微服務
是否我們達到了 Martin Fowler 講的以上 6 點就是 “微服務”,或者說是否一定要達到以上的 6 點才能稱之為 “微服務”。其實也不一定 Adrian Cockcroft 之前也給過微服務一個定義
Loosely coupled service oriented architecture with bounded contexts.
只要是 “松散耦合的、面向服務的、基于有界上下文的” 也可以成為微服務??梢娢⒎詹]有一個并沒有百分百的定義,更多是一種風格,我們需要的是理解這種風格對我們技術業務的推動。
2. 是否要實施微服務
上面我們整體的認識了什么是微服務,那么問題就來了,既然微服務已經這么火爆了,那于鏊不要在我們的業務中也實施微服務呢?
是否需要微服務這個問題的答案,要從實際業務中去得到:
2.1 單體應用的瓶頸
在以往傳統的系統架構中,我們在構建一個單體結構一般都是由:前端展示層,服務業務層,存儲數據層來組成。
業務發展初期,由于所有的業務邏輯都在一個應用中。開發,測試,部署來說都比較的輕量和方便。但隨著業務的發展,系統為了對應不同的業務就得往單體項目增加不同的業務模塊,慢慢的不斷追加的業務模塊會使得單體應用變得越來越臃腫。
隨著時間的增長,所有的業務都在一個應用里面,往往一個很小的功能修改都可能影響到其他的功能運行。
并且,在單體應用中,各個模塊的使用場景,并發量和系統所需要消耗的資源各不相同,資源處在于相互影響和相互競爭,這個就導致了我們很難去評估和預估所需要提供的資源。
上述說的問題,微服務的誕生就是為了解決單體系統變得臃腫難以維系的問題,將不同的功能點拆分不同服務,讓服務各自獨立運行,同時,由于是獨立運行,我們也可以更好的評估每個服務所需要的資源。
2.2 應用微服務的時機
剛剛上述說了微服務可以解決單體應用在臃腫的業務,部署難度大,資源和擴展難以評估,阻礙團隊的技術革新等問題,那是否我們就可以直接從單體應用轉化為微服務?
答案明顯并不是這樣,下面是 Martin Fowler 給的 微服務 / 單體 在隨著業務和時間進度推移反映到生產力的關系圖:
根據上圖,我們知道生產力和業務的復雜度是有關系的,在復雜度小的時候采用單體應用生產力會更高,但到了一定得規模,中間有一個臨界點,只有過了這個臨界點,單體服務的生產力直線下降,這個時候采用微服務才能正在的提升效率。
所以,要不要采用微服務架構,何時采用微服務必須根據業務場景去做評估,實施微服務對架構也提出來很多的挑戰,拆分服務也帶來了在單體應用中所沒有的問題:
例如服務治理的問題,雖然說微服務實現了最小化集中管理,但那是建立在有一個統一良好的治理體系里面,如果忽略治理也可能因為某個局部服務造成整體服務的崩塌。還有分布式所帶來一系列復雜性的問題,運維會迎來新的挑戰,需要運維的進程數量會大大的增加,還有如何將這些服務進行編排也是一個比較重要的問題。
這一系列的問題將在后面得章節中討論,要從一個單體應用轉型為微服務應用需要做什么呢,請看下一小節《單體服務轉為微服務體系需要注意什么問題?》。