...

架構之:微服務架構漫談

2021-06-29

目錄

簡介

    微服務和單體服務

    微服務的特征

    組件服務化

    組織的劃分

    服務之間的通信

    去中心化治理

    去中心化數據管理

    自動化部署

    對(duì)異常的響應

總結

簡介

微服務的架構出現已經(jīng)很久很久了,微服務架構就(jiù)是一種(zhǒng)將(jiāng)單個應用程序轉換爲一組小服務的方法,每個小服務都(dōu)在自己的進(jìn)程中運行,并使用輕量級的交互方式(如HTTP)進(jìn)行通信。

服務的劃分是根據具體的業務來的,并且可以通過(guò)完全自動化的部署機制獨立部署。雖然大家都(dōu)在談論微服務,但是什麼(me)時(shí)候應該使用微服務,使用微服務需要注意哪些問題對(duì)于很多人來說(shuō)仍然是一個模糊的概念。本文將(jiāng)會(huì)和大家一起(qǐ)探讨一下微服務相關的一些問題。

微服務和單體服務

在最開(kāi)始的程序體系中,通常都(dōu)是單體服務。對(duì)于單體服務來說(shuō),所有的服務都(dōu)在一個進(jìn)程中。企業應用程序通常由三個主要部分構建: 客戶端用戶界面(miàn)(由 HTML 頁面(miàn)和在用戶機器上的浏覽器中運行的 javascript 組成(chéng)),數據庫(由插入到公共的、通常是關系的數據庫管理中的許多表組成(chéng)系統)和服務器端應用程序。

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

對(duì)于單體服務來說(shuō),所有的處理請求邏輯都(dōu)在單個進(jìn)程中運行,爲了結構化和代碼編寫規範,通常會(huì)使用編程語言的基本功能(néng)將(jiāng)應用程序劃分爲類、函數和命名空間等。

雖然單體服務也可以通過(guò)負載均衡器後(hòu)面(miàn)運行多個實例來水平擴展應用,但是随著(zhe)服務器端業務越來越複雜,對(duì)于服務的每一次很小的變動都(dōu)會(huì)導緻對(duì)于整體服務的重新構建和部署。并且随著(zhe)時(shí)間的推移,通常很難保持良好(hǎo)的模塊化結構,和對(duì)現有架構進(jìn)行擴展。同時(shí)因爲單體服務在一個進(jìn)程中運行,如果該進(jìn)程出現運行時(shí)問題,會(huì)導緻所有的服務不可用,穩定性不夠。

 俗話說(shuō)得好(hǎo),雞蛋不能(néng)放在一個籃子裡(lǐ)面(miàn)。

于是把巨大的單體服務拆分成(chéng)爲一個個的微服務就(jiù)是現在系統架構的熱潮。

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

微服務的特征

微服務有些什麼(me)特征呢?什麼(me)樣(yàng)的服務才能(néng)被(bèi)稱爲是微服務呢?

社會(huì)很複雜,單純的是人。實際工程上的問題,不會(huì)向(xiàng)書本上學(xué)到的知識那樣(yàng),有一個明确定義。事(shì)實上,出了學(xué)校之後(hòu),這(zhè)個世界上的事(shì)情已經(jīng)不是非黑即白了。

比如,我們上學(xué)時(shí)候學(xué)到的圓的定義,它清晰的告訴我們,什麼(me)是圓。而對(duì)于微服務來說(shuō),則并沒(méi)有這(zhè)樣(yàng)的定義。

因爲微服務是在不斷的實踐中總結摸索出來的一種(zhǒng)架構。雖然不同的人對(duì)微服務有不同的理解,但是他們應該都(dōu)具有下面(miàn)幾個共同的特征。

組件服務化

自從軟件變得複雜之後(hòu),爲了更好(hǎo)的進(jìn)行軟件開(kāi)發(fā)和後(hòu)續的擴展,軟件逐漸開(kāi)始組件化。所謂組件就(jiù)是一個個的可以獨立替換和升級的部件。

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

這(zhè)些lib可以在運行時(shí)鏈接到程序中,以内存中的函數進(jìn)行運行。

有了鏈接的lib,爲什麼(me)我們還(hái)需要將(jiāng)這(zhè)些組件服務化,以單獨的進(jìn)程來運行呢?

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

但是,如果該應用程序分解爲多個服務,那麼(me)對(duì)于該服務的變更,隻需要重新部署該服務即可。雖然這(zhè)不是絕對(duì)的,因爲有些服務的變化會(huì)導緻對(duì)應的調用接口的變化,所以也需要對(duì)應的服務來進(jìn)行修改和适配。但是一個好(hǎo)的微服務架構的目标是通過(guò)服務契約中的内聚服務邊界和演化機制來最小化這(zhè)些變動。

使用服務作爲組件的另一個好(hǎo)處是更明确的組件接口。大多數語言沒(méi)有定義顯式發(fā)布接口的良好(hǎo)機制,從而導緻組件之間的耦合過(guò)于緊密。通過(guò)使用顯式遠程調用機制,服務可以更容易的進(jìn)行定義。

使用服務也有他的缺點,因爲服務之間是通過(guò)遠程調用的,遠程調用比進(jìn)程内調用更昂貴,所以服務之間的調用通常是更加粗粒度的調用,所以我們在界定服務的時(shí)候,需要劃分明确的職責分配。

組織的劃分

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

通常來說(shuō),對(duì)于大型的系統可以分爲UI團隊,服務邏輯團隊和數據庫團隊。但是這(zhè)樣(yàng)的組織方式就(jiù)會(huì)導緻一個團隊的改動需要其他團隊也進(jìn)行改動來配合。

所以在微服務中,組織應該是安裝具體的業務來劃分,這(zhè)樣(yàng)能(néng)夠保證組織的靈活性。

服務之間的通信

對(duì)于單體服務而言,依賴的lib是通過(guò)内部函數的調用來實現的,它的好(hǎo)處就(jiù)是速度快,但是如果將(jiāng)單體服務轉換成(chéng)微服務,就(jiù)需要考慮到服務之間的相互調用問題。

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

最常見的就(jiù)是HTTP/HTTPS協議之間的調用,這(zhè)種(zhǒng)方式的好(hǎo)處就(jiù)是協議簡單通用,兼容性的成(chéng)本較低。

如果是跨語言的,通常會(huì)用Thrift之類的RPC遠程調用協議,這(zhè)種(zhǒng)方式的好(hǎo)處就(jiù)是會(huì)比HTTP調用要快,但是調用起(qǐ)來比較複雜。需要構建特定的客戶端。

上面(miàn)講的是同步調用,如果是異步的話,還(hái)可以使用MQ機制,MQ的作用一是可以削峰,二是可以解耦。

去中心化治理

對(duì)于微服務來說(shuō),并不要求所有的微服務都(dōu)采用同一種(zhǒng)語言,同一種(zhǒng)架構方式來進(jìn)行。通常來說(shuō)了保證系統和代碼的可維護性,一般來說(shuō)是要求所有的服務都(dōu)使用同樣(yàng)的編程語言和架構。

但是對(duì)于特别的部分,比如對(duì)性能(néng)要求特别高這(zhè)樣(yàng)的需求,那麼(me)可以嘗試考慮一個不同的編程語言。

總的來說(shuō),就(jiù)是每個微服務的團隊對(duì)他們自己的服務負責,隻需要保證對(duì)外的服務和接口的正确性即可。

去中心化數據管理

對(duì)于單體應用來說(shuō), 所有的數據都(dōu)放在一個數據庫中。如果對(duì)微服務進(jìn)行了去中心化管理,那麼(me)相應的數據庫屬于各個微服務組,所以在理論上微服務的數據也應該是去中心化部署的。

但是這(zhè)樣(yàng)多個數據庫照成(chéng)的後(hòu)果就(jiù)是各個數據庫中數據的一緻性。在單體應用中,這(zhè)個問題可以通過(guò)數據庫事(shì)務來解決。但是對(duì)于微服務來說(shuō),分布式事(shì)務是不可行的,或者說(shuō)代價太大。一般來說(shuō)對(duì)于微服務來說(shuō),我們需要保證數據的最終一緻性。

通過(guò)補償機制來進(jìn)行數據的校驗和修複。

自動化部署

自動化部署的目标就(jiù)是持續交付,對(duì)于微服務來說(shuō),多個服務的自動化是必不可少的。通過(guò)自動化編譯,自動化測試,自動化集成(chéng)和自動化部署,可以大大的減輕開(kāi)發(fā)團隊和運維團隊的任務。提升開(kāi)發(fā)效率。

對(duì)異常的響應

使用服務作爲組件的結果是,應用程序需要設計成(chéng)可以容忍服務失敗。 任何服務調用都(dōu)可能(néng)因網絡或者其他的原因導緻不可用而失敗,所以必須盡可能(néng)優雅地對(duì)此做出響應。

于單體服務相比,這(zhè)需要引入額外的複雜性來處理它,所以可以看做是微服務的一個缺點。開(kāi)發(fā)團隊需要盡量多做異常測試,以保證在極端的環境中程序的正确性。

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

我們希望看到針對(duì)每個單獨服務的複雜監控和日志記錄設置,例如顯示啓動/關閉狀态的儀表闆以及各種(zhǒng)運營和業務相關指标,還(hái)包括有關斷路器狀态、當前吞吐量和延遲的詳細信息等。

總結

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

最後(hòu),問大家一個問題,在現實的項目中,有很多人希望把現有的單體服務拆分成(chéng)爲微服務,但是各個微服務還(hái)是共享著(zhe)同一個數據庫,也就(jiù)是說(shuō)這(zhè)些微服務之間還(hái)存在著(zhe)數據交叉。那麼(me)這(zhè)種(zhǒng)微服務算不算是真正的微服務呢?

來源:cnblogs