從0開始學微服務:01 到底什麼是微服務?

從0開始學微服務:01 到底什麼是微服務?

從谷歌的搜索指數來看,微服務的熱度在進入 2017 年後突然爆發,國內各大會議和論壇的相關討論也如雨後春筍般層出不窮,各大一線互聯網公司也紛紛將這一技術引入並在實際業務中落地。

從0開始學微服務:01 到底什麼是微服務?

然而據我所知,國內不少中小規模的技術團隊對微服務的概念都不甚瞭解,對該不該引入微服務也不置可否。還有一些技術團隊,沒有考慮實際業務場景,只是為了追求技術熱點,盲目引入微服務,但又缺乏相應的技術掌控能力,最後影響了業務的穩定性。

對於該不該引入微服務,以及微服務體系需要哪些技術,目前並沒有適合中小團隊的架構實踐落地的指引。因此我結合自己在微博多年的業務實踐,總結出了一套微服務落地經驗,從基礎理論到架構實踐,再結合業界最新趨勢分析,希望能幫助中小規模團隊瞭解微服務的本質以及對業務的價值,從而做出正確的判斷。

先來看看維基百科是如何定義微服務的。微服務的概念最早是在 2014 年由 Martin Fowler 和 James Lewis 共同提出,他們定義了微服務是由單一應用程序構成的小服務,擁有自己的進程與輕量化處理,服務依業務功能設計,以全自動的方式部署,與其他服務使用 HTTP API 通訊。同時,服務會使用最小規模的集中管理 (例如 Docker)技術,服務可以用不同的編程語言與數據庫等。

這個理論的定義看著有點暈?沒關係,接下來我來幫你理解到底什麼是微服務?

單體應用

在開聊微服務之前,我先要你和介紹下單體應用。如果你不知道單體應用的痛,那也不會深刻理解微服務的價值。

早些年,各大互聯網公司的應用技術棧大致可分為 LAMP(Linux + Apache + MySQL + PHP)和 MVC(Spring + iBatis/Hibernate + Tomcat)兩大流派。無論是 LAMP 還是 MVC,都是為單體應用架構設計的,其優點是學習成本低,開發上手快,測試、部署、運維也比較方便,甚至一個人就可以完成一個網站的開發與部署。

以 MVC 架構為例,業務通常是通過部署一個 WAR 包到 Tomcat 中,然後啟動 Tomcat,監聽某個端口即可對外提供服務。早期在業務規模不大、開發團隊人員規模較小的時候,採用單體應用架構,團隊的開發和運維成本都可控。

然而隨著業務規模的不斷擴大,團隊開發人員的不斷擴張,單體應用架構就會開始出現問題。我估計經歷過業務和團隊快速增長的同學都會對此深有感觸。從我的角度來看,大概會有以下幾個方面的問題。

  • 部署效率低下
    。以我實際參與的項目為例,當單體應用的代碼越來越多,依賴的資源越來越多時,應用編譯打包、部署測試一次,甚至需要 10 分鐘以上。這也經常被新加入的同學吐槽說,部署測試一次的時間,都可以去樓下喝杯咖啡了。
  • 團隊協作開發成本高。以我的經驗,早期在團隊開發人員只有兩三個人的時候,協作修改代碼,最後合併到同一個 master 分支,然後打包部署,尚且可控。但是一旦團隊人員擴張,超過 5 人修改代碼,然後一起打包部署,測試階段只要有一塊功能有問題,就得重新編譯打包部署,然後重新預覽測試,所有相關的開發人員又都得參與其中,效率低下,開發成本極高。
  • 系統高可用性差。因為所有的功能開發最後都部署到同一個 WAR 包裡,運行在同一個 Tomcat 進程之中,一旦某一功能涉及的代碼或者資源有問題,那就會影響整個 WAR 包中部署的功能。比如我經常遇到的一個問題,某段代碼不斷在內存中創建大對象,並且沒有回收,部署到線上運行一段時間後,就會造成 JVM 內存洩露,異常退出,那麼部署在同一個 JVM 進程中的所有服務都不可用,後果十分嚴重。
  • 線上發佈變慢。特別是對於 Java 應用來說,一旦代碼膨脹,服務啟動的時間就會變長,有些甚至超過 10 分鐘以上,如果機器規模超過 100 臺以上,假設每次發佈的步長為 10%,單次發佈需要就需要 100 分鐘之久。因此,急需一種方法能夠將應用的不同模塊的解耦,降低開發和部署成本。

想要解決上面這些問題,服務化的思想也就應運而生。

什麼是服務化?

這裡就不談一些官方的、教條主義的概念了。用通俗的話來講,服務化就是把傳統的單機應用中通過 JAR 包依賴產生的本地方法調用,改造成通過 RPC 接口產生的遠程方法調用。一般在編寫業務代碼時,對於一些通用的業務邏輯,我會盡力把它抽象並獨立成為專門的模塊,因為這對於代碼複用和業務理解都大有裨益。

在過去的項目經歷裡,我對此深有體會。以微博系統為例,微博既包含了內容模塊,也包含了消息模塊和用戶模塊等。其中消息模塊依賴內容模塊,消息模塊和內容模塊又都依賴用戶模塊。當這三個模塊的代碼耦合在一起,應用啟動時,需要同時去加載每個模塊的代碼並連接對應的資源。一旦任何模塊的代碼出現 bug,或者依賴的資源出現問題,整個單體應用都會受到影響。

為此,首先可以把用戶模塊從單體應用中拆分出來,獨立成一個服務部署,以 RPC 接口的形式對外提供服務。微博和消息模塊調用用戶接口,就從進程內的調用變成遠程 RPC 調用。這樣,用戶模塊就可以獨立開發、測試、上線和運維,可以交由專門的團隊來做,與主模塊不耦合。進一步的可以再把消息模塊也拆分出來作為獨立的模塊,交由專門的團隊來開發和維護。

可見通過服務化,可以解決單體應用膨脹、團隊開發耦合度高、協作效率低下的問題。

什麼是微服務?

從 2014 年開始,得益於以 Docker 為代表的容器化技術的成熟以及 DevOps 文化的興起,服務化的思想進一步演化,演變為今天我們所熟知的微服務。

那麼微服務相比於服務化又有什麼不同呢?

在我看來,可以總結為以下四點:

  • 服務拆分粒度更細。微服務可以說是更細維度的服務化,小到一個子模塊,只要該模塊依賴的資源與其他模塊都沒有關係,那麼就可以拆分為一個微服務。
  • 服務獨立部署。每個微服務都嚴格遵循獨立打包部署的準則,互不影響。比如一臺物理機上可以部署多個 Docker 實例,每個 Docker 實例可以部署一個微服務的代碼。
  • 服務獨立維護。每個微服務都可以交由一個小團隊甚至個人來開發、測試、發佈和運維,並對整個生命週期負責。
  • 服務治理能力要求高。因為拆分為微服務之後,服務的數量變多,因此需要有統一的服務治理平臺,來對各個服務進行管理。

繼續以前面舉的微博系統為例,可以進一步對內容模塊的功能進行拆分,比如內容模塊又包含了 feed 模塊、評論模塊和個人頁模塊。通過微服務化,將這三個模塊變成三個獨立的服務,每個服務依賴各自的資源,並獨立部署在不同的服務池中,可以由不同的開發人員進行維護。當評論服務需求變更時,只需要修改評論業務相關的代碼,並獨立上線發佈;而 feed 服務和個人頁服務不需要變更,也不會受到發佈可能帶來的變更影響。

由此可見,微服務化給服務的發佈和部署,以及服務的保障帶來了諸多好處。

總結

今天,我介紹了微服務的發展由來,它是由單體應用進化到服務化拆分部署,後期隨著移動互聯網規模的不斷擴大,敏捷開發、持續交付、DevOps 理論的發展和實踐,以及基於 Docker 容器化技術的成熟,微服務架構開始流行,逐漸成為應用架構的未來演進方向。

總結來說,微服務架構是將複雜臃腫的單體應用進行細粒度的服務化拆分,每個拆分出來的服務各自獨立打包部署,並交由小團隊進行開發和運維,從而極大地提高了應用交付的週期,並被各大互聯網公司所普遍採用。

思考題

你在業務開發中是否也遇到過因單體應用過度膨脹所帶來的問題呢?你覺得針對這些問題微服務能解決嗎?

歡迎你在留言區寫下自己的思考,與我一起討論。


分享到:


相關文章: