漫談架構(gòu)之微服務(wù)
一、簡介
服務(wù)的劃分是根據(jù)具體的業(yè)務(wù)來的,并且可以通過完全自動(dòng)化的部署機(jī)制獨(dú)立部署。雖然大家都在談?wù)撐⒎?wù),但是什么時(shí)候應(yīng)該使用微服務(wù),使用微服務(wù)需要注意哪些問題對于很多人來說仍然是一個(gè)模糊的概念。本文將會和大家一起探討一下微服務(wù)相關(guān)的一些問題。
二、微服務(wù)和單體服務(wù)
在最開始的程序體系中,通常都是單體服務(wù)。對于單體服務(wù)來說,所有的服務(wù)都在一個(gè)進(jìn)程中。企業(yè)應(yīng)用程序通常由三個(gè)主要部分構(gòu)建: 客戶端用戶界面(由 HTML 頁面和在用戶機(jī)器上的瀏覽器中運(yùn)行的 javascript 組成),數(shù)據(jù)庫(由插入到公共的、通常是關(guān)系的數(shù)據(jù)庫管理中的許多表組成系統(tǒng))和服務(wù)器端應(yīng)用程序。
服務(wù)器端應(yīng)用程序?qū)⑻幚?HTTP 請求、執(zhí)行域邏輯、從數(shù)據(jù)庫檢索和更新數(shù)據(jù),以及選擇和填充要發(fā)送到瀏覽器的 HTML 視圖。這個(gè)服務(wù)器端應(yīng)用程序是一個(gè)整體,也就是一個(gè)單獨(dú)的進(jìn)程。對系統(tǒng)的任何更改都需要重新構(gòu)建和部署服務(wù)器端應(yīng)用程序的最新版本。
對于單體服務(wù)來說,所有的處理請求邏輯都在單個(gè)進(jìn)程中運(yùn)行,為了結(jié)構(gòu)化和代碼編寫規(guī)范,通常會使用編程語言的基本功能將應(yīng)用程序劃分為類、函數(shù)和命名空間等。
雖然單體服務(wù)也可以通過負(fù)載均衡器后面運(yùn)行多個(gè)實(shí)例來水平擴(kuò)展應(yīng)用,但是隨著服務(wù)器端業(yè)務(wù)越來越復(fù)雜,對于服務(wù)的每一次很小的變動(dòng)都會導(dǎo)致對于整體服務(wù)的重新構(gòu)建和部署。并且隨著時(shí)間的推移,通常很難保持良好的模塊化結(jié)構(gòu),和對現(xiàn)有架構(gòu)進(jìn)行擴(kuò)展。同時(shí)因?yàn)閱误w服務(wù)在一個(gè)進(jìn)程中運(yùn)行,如果該進(jìn)程出現(xiàn)運(yùn)行時(shí)問題,會導(dǎo)致所有的服務(wù)不可用,穩(wěn)定性不夠。
俗話說得好,雞蛋不能放在一個(gè)籃子里面。
于是把巨大的單體服務(wù)拆分成為一個(gè)個(gè)的微服務(wù)就是現(xiàn)在系統(tǒng)架構(gòu)的熱潮。
微服務(wù)架構(gòu)就是將單體的應(yīng)用程序拆分為一個(gè)個(gè)的服務(wù),這些服務(wù)可以獨(dú)立部署和擴(kuò)展,并且服務(wù)之間有牢固的模塊邊界,服務(wù)之間主要通過HTTP協(xié)議進(jìn)行交互。因?yàn)榉?wù)之間是無內(nèi)部耦合的,所以我們可以甚至使用不同的編程語言來實(shí)現(xiàn)不同的服務(wù)。提高了程序的靈活性。
三、微服務(wù)的特征
微服務(wù)有些什么特征呢?什么樣的服務(wù)才能被稱為是微服務(wù)呢?
社會很復(fù)雜,單純的是人。實(shí)際工程上的問題,不會向書本上學(xué)到的知識那樣,有一個(gè)明確定義。事實(shí)上,出了學(xué)校之后,這個(gè)世界上的事情已經(jīng)不是非黑即白了。
比如,我們上學(xué)時(shí)候?qū)W到的圓的定義,它清晰的告訴我們,什么是圓。而對于微服務(wù)來說,則并沒有這樣的定義。
因?yàn)槲⒎?wù)是在不斷的實(shí)踐中總結(jié)摸索出來的一種架構(gòu)。雖然不同的人對微服務(wù)有不同的理解,但是他們應(yīng)該都具有下面幾個(gè)共同的特征。
3.1、組件服務(wù)化
自從軟件變得復(fù)雜之后,為了更好的進(jìn)行軟件開發(fā)和后續(xù)的擴(kuò)展,軟件逐漸開始組件化。所謂組件就是一個(gè)個(gè)的可以獨(dú)立替換和升級的部件。
現(xiàn)代程序中有很多可以稱之為組件的東西,比如java中的依賴jar包,python中的依賴包等。
這些lib可以在運(yùn)行時(shí)鏈接到程序中,以內(nèi)存中的函數(shù)進(jìn)行運(yùn)行。
有了鏈接的lib,為什么我們還需要將這些組件服務(wù)化,以單獨(dú)的進(jìn)程來運(yùn)行呢?
使用服務(wù)作為組件(而不是庫)的一個(gè)主要原因是服務(wù)是可獨(dú)立部署的。如果您的應(yīng)用程序 由單個(gè)進(jìn)程中的多個(gè)庫組成,則對任何單個(gè)組件的更改都會導(dǎo)致必須重新部署整個(gè)應(yīng)用程序。
但是,如果該應(yīng)用程序分解為多個(gè)服務(wù),那么對于該服務(wù)的變更,只需要重新部署該服務(wù)即可。雖然這不是絕對的,因?yàn)橛行┓?wù)的變化會導(dǎo)致對應(yīng)的調(diào)用接口的變化,所以也需要對應(yīng)的服務(wù)來進(jìn)行修改和適配。但是一個(gè)好的微服務(wù)架構(gòu)的目標(biāo)是通過服務(wù)契約中的內(nèi)聚服務(wù)邊界和演化機(jī)制來最小化這些變動(dòng)。
使用服務(wù)作為組件的另一個(gè)好處是更明確的組件接口。大多數(shù)語言沒有定義顯式發(fā)布接口的良好機(jī)制,從而導(dǎo)致組件之間的耦合過于緊密。通過使用顯式遠(yuǎn)程調(diào)用機(jī)制,服務(wù)可以更容易的進(jìn)行定義。
使用服務(wù)也有他的缺點(diǎn),因?yàn)榉?wù)之間是通過遠(yuǎn)程調(diào)用的,遠(yuǎn)程調(diào)用比進(jìn)程內(nèi)調(diào)用更昂貴,所以服務(wù)之間的調(diào)用通常是更加粗粒度的調(diào)用,所以我們在界定服務(wù)的時(shí)候,需要?jiǎng)澐置鞔_的職責(zé)分配。
3.2、組織的劃分
根據(jù)康威定律:組織溝通方式?jīng)Q定系統(tǒng)設(shè)計(jì)。
通常來說,對于大型的系統(tǒng)可以分為UI團(tuán)隊(duì),服務(wù)邏輯團(tuán)隊(duì)和數(shù)據(jù)庫團(tuán)隊(duì)。但是這樣的組織方式就會導(dǎo)致一個(gè)團(tuán)隊(duì)的改動(dòng)需要其他團(tuán)隊(duì)也進(jìn)行改動(dòng)來配合。
所以在微服務(wù)中,組織應(yīng)該是安裝具體的業(yè)務(wù)來劃分,這樣能夠保證組織的靈活性。
3.3、服務(wù)之間的通信
對于單體服務(wù)而言,依賴的lib是通過內(nèi)部函數(shù)的調(diào)用來實(shí)現(xiàn)的,它的好處就是速度快,但是如果將單體服務(wù)轉(zhuǎn)換成微服務(wù),就需要考慮到服務(wù)之間的相互調(diào)用問題。
常見的服務(wù)之間的調(diào)用方式有哪些呢?
最常見的就是HTTP/HTTPS協(xié)議之間的調(diào)用,這種方式的好處就是協(xié)議簡單通用,兼容性的成本較低。
如果是跨語言的,通常會用Thrift之類的RPC遠(yuǎn)程調(diào)用協(xié)議,這種方式的好處就是會比HTTP調(diào)用要快,但是調(diào)用起來比較復(fù)雜。需要構(gòu)建特定的客戶端。
上面講的是同步調(diào)用,如果是異步的話,還可以使用MQ機(jī)制,MQ的作用一是可以削峰,二是可以解耦。
3.4、去中心化治理
對于微服務(wù)來說,并不要求所有的微服務(wù)都采用同一種語言,同一種架構(gòu)方式來進(jìn)行。通常來說了保證系統(tǒng)和代碼的可維護(hù)性,一般來說是要求所有的服務(wù)都使用同樣的編程語言和架構(gòu)。
但是對于特別的部分,比如對性能要求特別高這樣的需求,那么可以嘗試考慮一個(gè)不同的編程語言。
總的來說,就是每個(gè)微服務(wù)的團(tuán)隊(duì)對他們自己的服務(wù)負(fù)責(zé),只需要保證對外的服務(wù)和接口的正確性即可。
3.5、去中心化數(shù)據(jù)管理
對于單體應(yīng)用來說, 所有的數(shù)據(jù)都放在一個(gè)數(shù)據(jù)庫中。如果對微服務(wù)進(jìn)行了去中心化管理,那么相應(yīng)的數(shù)據(jù)庫屬于各個(gè)微服務(wù)組,所以在理論上微服務(wù)的數(shù)據(jù)也應(yīng)該是去中心化部署的。
但是這樣多個(gè)數(shù)據(jù)庫照成的后果就是各個(gè)數(shù)據(jù)庫中數(shù)據(jù)的一致性。在單體應(yīng)用中,這個(gè)問題可以通過數(shù)據(jù)庫事務(wù)來解決。但是對于微服務(wù)來說,分布式事務(wù)是不可行的,或者說代價(jià)太大。一般來說對于微服務(wù)來說,我們需要保證數(shù)據(jù)的最終一致性。
通過補(bǔ)償機(jī)制來進(jìn)行數(shù)據(jù)的校驗(yàn)和修復(fù)。
3.6、自動(dòng)化部署
自動(dòng)化部署的目標(biāo)就是持續(xù)交付,對于微服務(wù)來說,多個(gè)服務(wù)的自動(dòng)化是必不可少的。通過自動(dòng)化編譯,自動(dòng)化測試,自動(dòng)化集成和自動(dòng)化部署,可以大大的減輕開發(fā)團(tuán)隊(duì)和運(yùn)維團(tuán)隊(duì)的任務(wù)。提升開發(fā)效率。
3.7、對異常的響應(yīng)
使用服務(wù)作為組件的結(jié)果是,應(yīng)用程序需要設(shè)計(jì)成可以容忍服務(wù)失敗。 任何服務(wù)調(diào)用都可能因網(wǎng)絡(luò)或者其他的原因?qū)е虏豢捎枚?,所以必須盡可能優(yōu)雅地對此做出響應(yīng)。
于單體服務(wù)相比,這需要引入額外的復(fù)雜性來處理它,所以可以看做是微服務(wù)的一個(gè)缺點(diǎn)。開發(fā)團(tuán)隊(duì)需要盡量多做異常測試,以保證在極端的環(huán)境中程序的正確性。
由于服務(wù)隨時(shí)可能出現(xiàn)故障,因此能夠快速檢測故障并在可能的情況下自動(dòng)恢復(fù)服務(wù)非常重要。微服務(wù)應(yīng)用程序非常重視應(yīng)用程序的實(shí)時(shí)監(jiān)控,檢查架構(gòu)元素(數(shù)據(jù)庫每秒收到多少請求)和業(yè)務(wù)相關(guān)指標(biāo)(例如每分鐘收到多少訂單)。語義監(jiān)控可以提供錯(cuò)誤的早期預(yù)警系統(tǒng),讓開發(fā)團(tuán)隊(duì)跟進(jìn)和調(diào)查。 監(jiān)控對于快速發(fā)現(xiàn)不良的緊急行為并加以修復(fù)至關(guān)重要。
我們希望看到針對每個(gè)單獨(dú)服務(wù)的復(fù)雜監(jiān)控和日志記錄設(shè)置,例如顯示啟動(dòng)/關(guān)閉狀態(tài)的儀表板以及各種運(yùn)營和業(yè)務(wù)相關(guān)指標(biāo),還包括有關(guān)斷路器狀態(tài)、當(dāng)前吞吐量和延遲的詳細(xì)信息等。
四、總結(jié)
講了這么多微服務(wù)的特征,微服務(wù)雖然有他的靈活性的優(yōu)點(diǎn),但是如何劃分微服務(wù)的邊界,和對微服務(wù)的監(jiān)控是一個(gè)很復(fù)雜的問題,所以到底要不要使用微服務(wù)還留給讀者自己思考。
最后,問大家一個(gè)問題,在現(xiàn)實(shí)的項(xiàng)目中,有很多人希望把現(xiàn)有的單體服務(wù)拆分成為微服務(wù),但是各個(gè)微服務(wù)還是共享著同一個(gè)數(shù)據(jù)庫,也就是說這些微服務(wù)之間還存在著數(shù)據(jù)交叉。那么這種微服務(wù)算不算是真正的微服務(wù)呢?
以上就是漫談架構(gòu)之微服務(wù)的詳細(xì)內(nèi)容,更多關(guān)于架構(gòu)微服務(wù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解為什么現(xiàn)代系統(tǒng)需要一個(gè)新的編程模型
如今高要求的分布式系統(tǒng)的建造者遇到了不能完全由傳統(tǒng)的面向?qū)ο缶幊?OOP)模型解決的挑戰(zhàn),但這可以從Actor模型中獲益。2021-05-05nasm實(shí)現(xiàn)的用vmware運(yùn)行自做的linux啟動(dòng)盤的引導(dǎo)代碼
這個(gè)小的代碼的編寫和運(yùn)行還是能讓自己對系統(tǒng)啟動(dòng)有一個(gè)更深的認(rèn)識,不過有個(gè)不懂的就是怎么用ISO鏡像文件啟動(dòng),怎么將引導(dǎo)代碼寫入ISO鏡像文件,依然沒有找到很好的方法解決2013-04-04計(jì)算機(jī)網(wǎng)絡(luò)編程MQTT協(xié)議基礎(chǔ)原理詳解
這篇文章主要為大家介紹了計(jì)算機(jī)編程MQTT協(xié)議的基礎(chǔ)原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2021-11-11