本系列文章主要由risingstack系列博客的翻譯構(gòu)成,從 Node.js入手了解接觸當(dāng)下十分流行的微服務(wù)架構(gòu)食侮。
微服務(wù)之前:?jiǎn)误w式架構(gòu)
單體式架構(gòu)(monolithic way) 是軟件開發(fā)中很常用的模式钠导,尤其像 rails 等框架可以很方便的幫助我們實(shí)現(xiàn)一個(gè)初具規(guī)模的應(yīng)用懂更。這一個(gè)應(yīng)用提供我們所需的所有功能:處理 HTTP 請(qǐng)求深夯、執(zhí)行主要邏輯鄙陡、數(shù)據(jù)庫(kù)操作喻旷、與瀏覽器/客戶端通信生逸、鑒權(quán)處理等等。但是任何一處地方的改動(dòng)若想生效都需要重新構(gòu)建且预、部署整個(gè)應(yīng)用槽袄,這對(duì)大規(guī)模、含有老舊代碼的應(yīng)用帶來(lái)了嚴(yán)峻的挑戰(zhàn)锋谐,某個(gè)模塊中的 bug 就可能拖垮整個(gè)網(wǎng)站遍尺。但這還不是唯一的問題,在大規(guī)模應(yīng)用中涮拗,即使我們知道問題出在某個(gè)地方乾戏,我們還是必須要運(yùn)行所有的應(yīng)用實(shí)例來(lái)啟動(dòng)服務(wù),對(duì)開發(fā)人員來(lái)說(shuō)其開發(fā)成本也大幅上升三热。除此之外鼓择,我們?cè)陂_發(fā)代碼時(shí)一直在講究組件化、模塊化就漾,卻在部署應(yīng)用時(shí)讓仍然將其整體打包放到一個(gè)統(tǒng)一的環(huán)境中去呐能,當(dāng)一些模塊是 CPU 敏感而一些模塊是內(nèi)存敏感時(shí)就不得不對(duì)硬件作出妥協(xié)。
在下圖所示的應(yīng)用中抑堡,單體式架構(gòu)集成了所有的功能摆出。那么當(dāng)用戶大量上傳圖片時(shí)朗徊,用于處理圖片的接口的壓力與風(fēng)險(xiǎn)需要整個(gè)應(yīng)用來(lái)共同承擔(dān),因此對(duì)于主應(yīng)用的穩(wěn)定性提出了很大的挑戰(zhàn)偎漫。此時(shí)荣倾,通常有兩個(gè)選擇:一是通過(guò)運(yùn)行多個(gè)單體應(yīng)用的實(shí)例來(lái)擴(kuò)大規(guī)模;二是將這些邏輯放到微服務(wù)中骑丸。
轉(zhuǎn)化為微服務(wù)架構(gòu)
微服務(wù)是將原來(lái)一個(gè)巨大的單體應(yīng)用分解為多個(gè)微型的舌仍、可以互相連接的服務(wù)架構(gòu)。上文提到的單體應(yīng)用可以轉(zhuǎn)化為如下的微服務(wù)形式:
微服務(wù)的優(yōu)點(diǎn)
-
漸進(jìn)式設(shè)計(jì)
微服務(wù)最大的優(yōu)點(diǎn)就是永遠(yuǎn)不需要我們從頭重寫整個(gè)應(yīng)用程序通危,只要以微服務(wù)的形式增加新的功能铸豁,并插入到現(xiàn)有的應(yīng)用中即可。
-
易維護(hù)
每個(gè)微服務(wù)的功能代碼獨(dú)立存在菊碟,維護(hù)成本低
-
擴(kuò)展性高
回到上文提到的問題:如果你的用戶們突然大量上傳圖片怎么辦节芥? 在微服務(wù)中,你可以只對(duì)處理圖片的 API 進(jìn)行擴(kuò)容逆害,這比單體式架構(gòu)中要處理整個(gè)應(yīng)用要好的多头镊,對(duì)么?
-
易部署
每個(gè)微服務(wù)只有少量的依賴魄幕,所以更容易部署相艇,很適合敏捷開發(fā)。
-
系統(tǒng)彈性大
因?yàn)檎麄€(gè)應(yīng)用是由多個(gè)微服務(wù)組成的纯陨,所以即使某些功能失效了也不會(huì)拖垮整個(gè)服務(wù)的運(yùn)行坛芽。
微服務(wù)帶來(lái)新的挑戰(zhàn)
微服務(wù)模式并不是系統(tǒng)設(shè)計(jì)的銀彈,它幫助我們解決了很多麻煩翼抠,但也帶來(lái)了很多新的挑戰(zhàn)咙轩。
-
微服務(wù)之間的通信
很多微服務(wù)之間會(huì)互相依賴,那么彼此的通信就是首先要面臨的問題阴颖。我們一起來(lái)看看最常見的選擇:
-
使用 HTTP APIs
微服務(wù)可以暴露 HTTP 接口以供其他服務(wù)使用活喊。為什么是HTTP?
HTTP是事實(shí)上的、標(biāo)準(zhǔn)的信息交換方式,每個(gè)語(yǔ)言都有某種類似的HTTP客戶端×坷ⅲ現(xiàn)在也有很多的工具集來(lái)幫助我們實(shí)現(xiàn)钾菊,并不用重新造輪子。 -
使用消息隊(duì)列
微服務(wù)之間另一種通信方式是使用消息隊(duì)列如 RabbitMQ或 ZeroMQ侠畔。這種通信方式在長(zhǎng)時(shí)間運(yùn)行任務(wù)或大量處理中非常有用结缚。一個(gè)很好的例子是 EmailAPI--當(dāng)一封郵件要被發(fā)送時(shí)就將其放入到一個(gè)隊(duì)列中损晤,然后 EmailAPI會(huì)依次處理并發(fā)送郵件软棺。
-
服務(wù)發(fā)現(xiàn)
當(dāng)微服務(wù)之間想要通信的時(shí)候,還必須能夠首先找到這些服務(wù)尤勋。為此喘落,我們需要一個(gè)具有一致性茵宪、高可用的分布式系統(tǒng)。以 Image API為例瘦棋,主應(yīng)用程序必須知道它在哪兒能夠找到它所需要的服務(wù)稀火,即主應(yīng)用程序需要能夠獲取到這些服務(wù)的地址。
有用的工具/庫(kù)
在這兒列出了一些常用來(lái)構(gòu)建微服務(wù)應(yīng)用的項(xiàng)目赌朋。通過(guò)接下來(lái)的文章凰狞,你會(huì)更加了解如何使用它們。
最后
這是接觸微服務(wù)系列文章的第一篇沛慢,接下來(lái)我們會(huì)探索如何在 Node 應(yīng)用中使用服務(wù)發(fā)現(xiàn)赡若。