...

架構之(zhī):微服務架構漫談

2021-06-29

目錄

簡介

    微服務和(hé / huò)單體服務

    微服務的(de)特征

    組件服務化

    組織的(de)劃分

    服務之(zhī)間的(de)通信

    去中心化治理

    去中心化數據管理

    自動化部署

    對異常的(de)響應

總結

簡介

微服務的(de)架構出(chū)現已經很久很久了(le/liǎo),微服務架構就(jiù)是(shì)一(yī / yì /yí)種将單個(gè)應用程序轉換爲(wéi / wèi)一(yī / yì /yí)組小服務的(de)方法,每個(gè)小服務都在(zài)自己的(de)進程中運行,并使用輕量級的(de)交互方式(如HTTP)進行通信。

服務的(de)劃分是(shì)根據具體的(de)業務來(lái)的(de),并且可以(yǐ)通過完全自動化的(de)部署機制獨立部署。雖然大(dà)家都在(zài)談論微服務,但是(shì)什麽時(shí)候應該使用微服務,使用微服務需要(yào / yāo)注意哪些問題對于(yú)很多人(rén)來(lái)說(shuō)仍然是(shì)一(yī / yì /yí)個(gè)模糊的(de)概念。本文将會和(hé / huò)大(dà)家一(yī / yì /yí)起探讨一(yī / yì /yí)下微服務相關的(de)一(yī / yì /yí)些問題。

微服務和(hé / huò)單體服務

在(zài)最開始的(de)程序體系中,通常都是(shì)單體服務。對于(yú)單體服務來(lái)說(shuō),所有的(de)服務都在(zài)一(yī / yì /yí)個(gè)進程中。企業應用程序通常由三個(gè)主要(yào / yāo)部分構建: 客戶端用戶界面(由 HTML 頁面和(hé / huò)在(zài)用戶機器上(shàng)的(de)浏覽器中運行的(de) javascript 組成),數據庫(由插入到(dào)公共的(de)、通常是(shì)關系的(de)數據庫管理中的(de)許多表組成系統)和(hé / huò)服務器端應用程序。

服務器端應用程序将處理 HTTP 請求、執行域邏輯、從數據庫檢索和(hé / huò)更新數據,以(yǐ)及選擇和(hé / huò)填充要(yào / yāo)發送到(dào)浏覽器的(de) HTML 視圖。這(zhè)個(gè)服務器端應用程序是(shì)一(yī / yì /yí)個(gè)整體,也(yě)就(jiù)是(shì)一(yī / yì /yí)個(gè)單獨的(de)進程。對系統的(de)任何更改都需要(yào / yāo)重新構建和(hé / huò)部署服務器端應用程序的(de)最新版本。

對于(yú)單體服務來(lái)說(shuō),所有的(de)處理請求邏輯都在(zài)單個(gè)進程中運行,爲(wéi / wèi)了(le/liǎo)結構化和(hé / huò)代碼編寫規範,通常會使用編程語言的(de)基本功能将應用程序劃分爲(wéi / wèi)類、函數和(hé / huò)命名空間等。

雖然單體服務也(yě)可以(yǐ)通過負載均衡器後面運行多個(gè)實例來(lái)水平擴展應用,但是(shì)随着服務器端業務越來(lái)越複雜,對于(yú)服務的(de)每一(yī / yì /yí)次很小的(de)變動都會導緻對于(yú)整體服務的(de)重新構建和(hé / huò)部署。并且随着時(shí)間的(de)推移,通常很難保持良好的(de)模塊化結構,和(hé / huò)對現有架構進行擴展。同時(shí)因爲(wéi / wèi)單體服務在(zài)一(yī / yì /yí)個(gè)進程中運行,如果該進程出(chū)現運行時(shí)問題,會導緻所有的(de)服務不(bù)可用,穩定性不(bù)夠。

 俗話說(shuō)得好,雞蛋不(bù)能放在(zài)一(yī / yì /yí)個(gè)籃子(zǐ)裏面。

于(yú)是(shì)把巨大(dà)的(de)單體服務拆分成爲(wéi / wèi)一(yī / yì /yí)個(gè)個(gè)的(de)微服務就(jiù)是(shì)現在(zài)系統架構的(de)熱潮。

微服務架構就(jiù)是(shì)将單體的(de)應用程序拆分爲(wéi / wèi)一(yī / yì /yí)個(gè)個(gè)的(de)服務,這(zhè)些服務可以(yǐ)獨立部署和(hé / huò)擴展,并且服務之(zhī)間有牢固的(de)模塊邊界,服務之(zhī)間主要(yào / yāo)通過HTTP協議進行交互。因爲(wéi / wèi)服務之(zhī)間是(shì)無内部耦合的(de),所以(yǐ)我們可以(yǐ)甚至使用不(bù)同的(de)編程語言來(lái)實現不(bù)同的(de)服務。提高了(le/liǎo)程序的(de)靈活性。

微服務的(de)特征

微服務有些什麽特征呢?什麽樣的(de)服務才能被稱爲(wéi / wèi)是(shì)微服務呢?

社會很複雜,單純的(de)是(shì)人(rén)。實際工程上(shàng)的(de)問題,不(bù)會向書本上(shàng)學到(dào)的(de)知識那樣,有一(yī / yì /yí)個(gè)明确定義。事實上(shàng),出(chū)了(le/liǎo)學校之(zhī)後,這(zhè)個(gè)世界上(shàng)的(de)事情已經不(bù)是(shì)非黑即白了(le/liǎo)。

比如,我們上(shàng)學時(shí)候學到(dào)的(de)圓的(de)定義,它清晰的(de)告訴我們,什麽是(shì)圓。而(ér)對于(yú)微服務來(lái)說(shuō),則并沒有這(zhè)樣的(de)定義。

因爲(wéi / wèi)微服務是(shì)在(zài)不(bù)斷的(de)實踐中總結摸索出(chū)來(lái)的(de)一(yī / yì /yí)種架構。雖然不(bù)同的(de)人(rén)對微服務有不(bù)同的(de)理解,但是(shì)他(tā)們應該都具有下面幾個(gè)共同的(de)特征。

組件服務化

自從軟件變得複雜之(zhī)後,爲(wéi / wèi)了(le/liǎo)更好的(de)進行軟件開發和(hé / huò)後續的(de)擴展,軟件逐漸開始組件化。所謂組件就(jiù)是(shì)一(yī / yì /yí)個(gè)個(gè)的(de)可以(yǐ)獨立替換和(hé / huò)升級的(de)部件。

現代程序中有很多可以(yǐ)稱之(zhī)爲(wéi / wèi)組件的(de)東西,比如java中的(de)依賴jar包,python中的(de)依賴包等。

這(zhè)些lib可以(yǐ)在(zài)運行時(shí)鏈接到(dào)程序中,以(yǐ)内存中的(de)函數進行運行。

有了(le/liǎo)鏈接的(de)lib,爲(wéi / wèi)什麽我們還需要(yào / yāo)将這(zhè)些組件服務化,以(yǐ)單獨的(de)進程來(lái)運行呢?

使用服務作爲(wéi / wèi)組件(而(ér)不(bù)是(shì)庫)的(de)一(yī / yì /yí)個(gè)主要(yào / yāo)原因是(shì)服務是(shì)可獨立部署的(de)。如果您的(de)應用程序 由單個(gè)進程中的(de)多個(gè)庫組成,則對任何單個(gè)組件的(de)更改都會導緻必須重新部署整個(gè)應用程序。

但是(shì),如果該應用程序分解爲(wéi / wèi)多個(gè)服務,那麽對于(yú)該服務的(de)變更,隻需要(yào / yāo)重新部署該服務即可。雖然這(zhè)不(bù)是(shì)絕對的(de),因爲(wéi / wèi)有些服務的(de)變化會導緻對應的(de)調用接口的(de)變化,所以(yǐ)也(yě)需要(yào / yāo)對應的(de)服務來(lái)進行修改和(hé / huò)适配。但是(shì)一(yī / yì /yí)個(gè)好的(de)微服務架構的(de)目标是(shì)通過服務契約中的(de)内聚服務邊界和(hé / huò)演化機制來(lái)最小化這(zhè)些變動。

使用服務作爲(wéi / wèi)組件的(de)另一(yī / yì /yí)個(gè)好處是(shì)更明确的(de)組件接口。大(dà)多數語言沒有定義顯式發布接口的(de)良好機制,從而(ér)導緻組件之(zhī)間的(de)耦合過于(yú)緊密。通過使用顯式遠程調用機制,服務可以(yǐ)更容易的(de)進行定義。

使用服務也(yě)有他(tā)的(de)缺點,因爲(wéi / wèi)服務之(zhī)間是(shì)通過遠程調用的(de),遠程調用比進程内調用更昂貴,所以(yǐ)服務之(zhī)間的(de)調用通常是(shì)更加粗粒度的(de)調用,所以(yǐ)我們在(zài)界定服務的(de)時(shí)候,需要(yào / yāo)劃分明确的(de)職責分配。

組織的(de)劃分

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

通常來(lái)說(shuō),對于(yú)大(dà)型的(de)系統可以(yǐ)分爲(wéi / wèi)UI團隊,服務邏輯團隊和(hé / huò)數據庫團隊。但是(shì)這(zhè)樣的(de)組織方式就(jiù)會導緻一(yī / yì /yí)個(gè)團隊的(de)改動需要(yào / yāo)其他(tā)團隊也(yě)進行改動來(lái)配合。

所以(yǐ)在(zài)微服務中,組織應該是(shì)安裝具體的(de)業務來(lái)劃分,這(zhè)樣能夠保證組織的(de)靈活性。

服務之(zhī)間的(de)通信

對于(yú)單體服務而(ér)言,依賴的(de)lib是(shì)通過内部函數的(de)調用來(lái)實現的(de),它的(de)好處就(jiù)是(shì)速度快,但是(shì)如果将單體服務轉換成微服務,就(jiù)需要(yào / yāo)考慮到(dào)服務之(zhī)間的(de)相互調用問題。

常見的(de)服務之(zhī)間的(de)調用方式有哪些呢?

最常見的(de)就(jiù)是(shì)HTTP/HTTPS協議之(zhī)間的(de)調用,這(zhè)種方式的(de)好處就(jiù)是(shì)協議簡單通用,兼容性的(de)成本較低。

如果是(shì)跨語言的(de),通常會用Thrift之(zhī)類的(de)RPC遠程調用協議,這(zhè)種方式的(de)好處就(jiù)是(shì)會比HTTP調用要(yào / yāo)快,但是(shì)調用起來(lái)比較複雜。需要(yào / yāo)構建特定的(de)客戶端。

上(shàng)面講的(de)是(shì)同步調用,如果是(shì)異步的(de)話,還可以(yǐ)使用MQ機制,MQ的(de)作用一(yī / yì /yí)是(shì)可以(yǐ)削峰,二是(shì)可以(yǐ)解耦。

去中心化治理

對于(yú)微服務來(lái)說(shuō),并不(bù)要(yào / yāo)求所有的(de)微服務都采用同一(yī / yì /yí)種語言,同一(yī / yì /yí)種架構方式來(lái)進行。通常來(lái)說(shuō)了(le/liǎo)保證系統和(hé / huò)代碼的(de)可維護性,一(yī / yì /yí)般來(lái)說(shuō)是(shì)要(yào / yāo)求所有的(de)服務都使用同樣的(de)編程語言和(hé / huò)架構。

但是(shì)對于(yú)特别的(de)部分,比如對性能要(yào / yāo)求特别高這(zhè)樣的(de)需求,那麽可以(yǐ)嘗試考慮一(yī / yì /yí)個(gè)不(bù)同的(de)編程語言。

總的(de)來(lái)說(shuō),就(jiù)是(shì)每個(gè)微服務的(de)團隊對他(tā)們自己的(de)服務負責,隻需要(yào / yāo)保證對外的(de)服務和(hé / huò)接口的(de)正确性即可。

去中心化數據管理

對于(yú)單體應用來(lái)說(shuō), 所有的(de)數據都放在(zài)一(yī / yì /yí)個(gè)數據庫中。如果對微服務進行了(le/liǎo)去中心化管理,那麽相應的(de)數據庫屬于(yú)各個(gè)微服務組,所以(yǐ)在(zài)理論上(shàng)微服務的(de)數據也(yě)應該是(shì)去中心化部署的(de)。

但是(shì)這(zhè)樣多個(gè)數據庫照成的(de)後果就(jiù)是(shì)各個(gè)數據庫中數據的(de)一(yī / yì /yí)緻性。在(zài)單體應用中,這(zhè)個(gè)問題可以(yǐ)通過數據庫事務來(lái)解決。但是(shì)對于(yú)微服務來(lái)說(shuō),分布式事務是(shì)不(bù)可行的(de),或者說(shuō)代價太大(dà)。一(yī / yì /yí)般來(lái)說(shuō)對于(yú)微服務來(lái)說(shuō),我們需要(yào / yāo)保證數據的(de)最終一(yī / yì /yí)緻性。

通過補償機制來(lái)進行數據的(de)校驗和(hé / huò)修複。

自動化部署

自動化部署的(de)目标就(jiù)是(shì)持續交付,對于(yú)微服務來(lái)說(shuō),多個(gè)服務的(de)自動化是(shì)必不(bù)可少的(de)。通過自動化編譯,自動化測試,自動化集成和(hé / huò)自動化部署,可以(yǐ)大(dà)大(dà)的(de)減輕開發團隊和(hé / huò)運維團隊的(de)任務。提升開發效率。

對異常的(de)響應

使用服務作爲(wéi / wèi)組件的(de)結果是(shì),應用程序需要(yào / yāo)設計成可以(yǐ)容忍服務失敗。 任何服務調用都可能因網絡或者其他(tā)的(de)原因導緻不(bù)可用而(ér)失敗,所以(yǐ)必須盡可能優雅地(dì / de)對此做出(chū)響應。

于(yú)單體服務相比,這(zhè)需要(yào / yāo)引入額外的(de)複雜性來(lái)處理它,所以(yǐ)可以(yǐ)看做是(shì)微服務的(de)一(yī / yì /yí)個(gè)缺點。開發團隊需要(yào / yāo)盡量多做異常測試,以(yǐ)保證在(zài)極端的(de)環境中程序的(de)正确性。

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

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

總結

講了(le/liǎo)這(zhè)麽多微服務的(de)特征,微服務雖然有他(tā)的(de)靈活性的(de)優點,但是(shì)如何劃分微服務的(de)邊界,和(hé / huò)對微服務的(de)監控是(shì)一(yī / yì /yí)個(gè)很複雜的(de)問題,所以(yǐ)到(dào)底要(yào / yāo)不(bù)要(yào / yāo)使用微服務還留給讀者自己思考。

最後,問大(dà)家一(yī / yì /yí)個(gè)問題,在(zài)現實的(de)項目中,有很多人(rén)希望把現有的(de)單體服務拆分成爲(wéi / wèi)微服務,但是(shì)各個(gè)微服務還是(shì)共享着同一(yī / yì /yí)個(gè)數據庫,也(yě)就(jiù)是(shì)說(shuō)這(zhè)些微服務之(zhī)間還存在(zài)着數據交叉。那麽這(zhè)種微服務算不(bù)算是(shì)真正的(de)微服務呢?

來(lái)源:cnblogs