架構之:微服務架構漫談 簡介 微服務和單體服務 微服務的特徵 總結

簡介

微服務的架構出現已經很久很久了,微服務架構就是一種將單個應用程序轉換爲一組小服務的方法,每個小服務都在自己的進程中運行,並使用輕量級的交互方式(如HTTP)進行通信。

服務的劃分是根據具體的業務來的,並且可以通過完全自動化的部署機制獨立部署。雖然大家都在談論微服務,但是什麼時候應該使用微服務,使用微服務需要注意哪些問題對於很多人來說仍然是一個模糊的概念。本文將會和大家一起探討一下微服務相關的一些問題。

微服務和單體服務

在最開始的程序體系中,通常都是單體服務。對於單體服務來說,所有的服務都在一個進程中。企業應用程序通常由三個主要部分構建: 客戶端用戶界面(由 HTML 頁面和在用戶機器上的瀏覽器中運行的 javascript 組成),數據庫(由插入到公共的、通常是關係的數據庫管理中的許多表組成系統)和服務器端應用程序。

服務器端應用程序將處理 HTTP 請求、執行域邏輯、從數據庫檢索和更新數據,以及選擇和填充要發送到瀏覽器的 HTML 視圖。這個服務器端應用程序是一個整體,也就是一個單獨的進程。對系統的任何更改都需要重新構建和部署服務器端應用程序的最新版本。

對於單體服務來說,所有的處理請求邏輯都在單個進程中運行,爲了結構化和代碼編寫規範,通常會使用編程語言的基本功能將應用程序劃分爲類、函數和命名空間等。

雖然單體服務也可以通過負載均衡器後面運行多個實例來水平擴展應用,但是隨着服務器端業務越來越複雜,對於服務的每一次很小的變動都會導致對於整體服務的重新構建和部署。並且隨着時間的推移,通常很難保持良好的模塊化結構,和對現有架構進行擴展。同時因爲單體服務在一個進程中運行,如果該進程出現運行時問題,會導致所有的服務不可用,穩定性不夠。

俗話說得好,雞蛋不能放在一個籃子裏面。

於是把巨大的單體服務拆分成爲一個個的微服務就是現在系統架構的熱潮。

微服務架構就是將單體的應用程序拆分爲一個個的服務,這些服務可以獨立部署和擴展,並且服務之間有牢固的模塊邊界,服務之間主要通過HTTP協議進行交互。因爲服務之間是無內部耦合的,所以我們可以甚至使用不同的編程語言來實現不同的服務。提高了程序的靈活性。

<img src="https://img-blog.csdnimg.cn/20210602170040451.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_0,text_aHR0cDovL3d3dy5mbHlkZWFuLmNvbQ==,size_25,color_8F8F8F,t_70" style="zoom:50%;" />

微服務的特徵

微服務有些什麼特徵呢?什麼樣的服務才能被稱爲是微服務呢?

社會很複雜,單純的是人。實際工程上的問題,不會向書本上學到的知識那樣,有一個明確定義。事實上,出了學校之後,這個世界上的事情已經不是非黑即白了。

比如,我們上學時候學到的圓的定義,它清晰的告訴我們,什麼是圓。而對於微服務來說,則並沒有這樣的定義。

因爲微服務是在不斷的實踐中總結摸索出來的一種架構。雖然不同的人對微服務有不同的理解,但是他們應該都具有下面幾個共同的特徵。

組件服務化

自從軟件變得複雜之後,爲了更好的進行軟件開發和後續的擴展,軟件逐漸開始組件化。所謂組件就是一個個的可以獨立替換和升級的部件。

現代程序中有很多可以稱之爲組件的東西,比如java中的依賴jar包,python中的依賴包等。

這些lib可以在運行時鏈接到程序中,以內存中的函數進行運行。

有了鏈接的lib,爲什麼我們還需要將這些組件服務化,以單獨的進程來運行呢?

使用服務作爲組件(而不是庫)的一個主要原因是服務是可獨立部署的。如果您的應用程序 由單個進程中的多個庫組成,則對任何單個組件的更改都會導致必須重新部署整個應用程序。

但是,如果該應用程序分解爲多個服務,那麼對於該服務的變更,只需要重新部署該服務即可。雖然這不是絕對的,因爲有些服務的變化會導致對應的調用接口的變化,所以也需要對應的服務來進行修改和適配。但是一個好的微服務架構的目標是通過服務契約中的內聚服務邊界和演化機制來最小化這些變動。

使用服務作爲組件的另一個好處是更明確的組件接口。大多數語言沒有定義顯式發佈接口的良好機制,從而導致組件之間的耦合過於緊密。通過使用顯式遠程調用機制,服務可以更容易的進行定義。

使用服務也有他的缺點,因爲服務之間是通過遠程調用的,遠程調用比進程內調用更昂貴,所以服務之間的調用通常是更加粗粒度的調用,所以我們在界定服務的時候,需要劃分明確的職責分配。

組織的劃分

根據康威定律:組織溝通方式決定系統設計。

通常來說,對於大型的系統可以分爲UI團隊,服務邏輯團隊和數據庫團隊。但是這樣的組織方式就會導致一個團隊的改動需要其他團隊也進行改動來配合。

所以在微服務中,組織應該是安裝具體的業務來劃分,這樣能夠保證組織的靈活性。

服務之間的通信

對於單體服務而言,依賴的lib是通過內部函數的調用來實現的,它的好處就是速度快,但是如果將單體服務轉換成微服務,就需要考慮到服務之間的相互調用問題。

常見的服務之間的調用方式有哪些呢?

最常見的就是HTTP/HTTPS協議之間的調用,這種方式的好處就是協議簡單通用,兼容性的成本較低。

如果是跨語言的,通常會用Thrift之類的RPC遠程調用協議,這種方式的好處就是會比HTTP調用要快,但是調用起來比較複雜。需要構建特定的客戶端。

上面講的是同步調用,如果是異步的話,還可以使用MQ機制,MQ的作用一是可以削峯,二是可以解耦。

去中心化治理

對於微服務來說,並不要求所有的微服務都採用同一種語言,同一種架構方式來進行。通常來說了保證系統和代碼的可維護性,一般來說是要求所有的服務都使用同樣的編程語言和架構。

但是對於特別的部分,比如對性能要求特別高這樣的需求,那麼可以嘗試考慮一個不同的編程語言。

總的來說,就是每個微服務的團隊對他們自己的服務負責,只需要保證對外的服務和接口的正確性即可。

去中心化數據管理

對於單體應用來說, 所有的數據都放在一個數據庫中。如果對微服務進行了去中心化管理,那麼相應的數據庫屬於各個微服務組,所以在理論上微服務的數據也應該是去中心化部署的。

但是這樣多個數據庫照成的後果就是各個數據庫中數據的一致性。在單體應用中,這個問題可以通過數據庫事務來解決。但是對於微服務來說,分佈式事務是不可行的,或者說代價太大。一般來說對於微服務來說,我們需要保證數據的最終一致性。

通過補償機制來進行數據的校驗和修復。

自動化部署

自動化部署的目標就是持續交付,對於微服務來說,多個服務的自動化是必不可少的。通過自動化編譯,自動化測試,自動化集成和自動化部署,可以大大的減輕開發團隊和運維團隊的任務。提升開發效率。

對異常的響應

使用服務作爲組件的結果是,應用程序需要設計成可以容忍服務失敗。 任何服務調用都可能因網絡或者其他的原因導致不可用而失敗,所以必須儘可能優雅地對此做出響應。

於單體服務相比,這需要引入額外的複雜性來處理它,所以可以看做是微服務的一個缺點。開發團隊需要儘量多做異常測試,以保證在極端的環境中程序的正確性。

由於服務隨時可能出現故障,因此能夠快速檢測故障並在可能的情況下自動恢復服務非常重要。微服務應用程序非常重視應用程序的實時監控,檢查架構元素(數據庫每秒收到多少請求)和業務相關指標(例如每分鐘收到多少訂單)。語義監控可以提供錯誤的早期預警系統,讓開發團隊跟進和調查。 監控對於快速發現不良的緊急行爲並加以修復至關重要。

我們希望看到針對每個單獨服務的複雜監控和日誌記錄設置,例如顯示啓動/關閉狀態的儀表板以及各種運營和業務相關指標,還包括有關斷路器狀態、當前吞吐量和延遲的詳細信息等。

總結

講了這麼多微服務的特徵,微服務雖然有他的靈活性的優點,但是如何劃分微服務的邊界,和對微服務的監控是一個很複雜的問題,所以到底要不要使用微服務還留給讀者自己思考。

最後,問大家一個問題,在現實的項目中,有很多人希望把現有的單體服務拆分成爲微服務,但是各個微服務還是共享着同一個數據庫,也就是說這些微服務之間還存在着數據交叉。那麼這種微服務算不算是真正的微服務呢?

本文已收錄於 http://www.flydean.com/09-microservices-guide/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!

歡迎關注我的公衆號:「程序那些事」,懂技術,更懂你!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章