這個(gè)問(wèn)題,其實(shí)也是很多人的疑問(wèn)!
我想說(shuō):
如果一個(gè)軟件開(kāi)發(fā)人員,不了解軟件架構(gòu)的演進(jìn),會(huì)制約技術(shù)的選型和開(kāi)發(fā)人員的生存、晉升空間。這里我列舉了目前主要的四種軟件架構(gòu)以及他們的優(yōu)缺點(diǎn),希望能夠幫助軟件開(kāi)發(fā)人員拓展知識(shí)面。
一、單體架構(gòu)
單體架構(gòu)比較初級(jí),典型的三級(jí)架構(gòu),前端(Web/手機(jī)端)+中間業(yè)務(wù)邏輯層+數(shù)據(jù)庫(kù)層。這是一種典型的JavaSpringmvc或者PythonDjango框架的應(yīng)用。其架構(gòu)圖如下所示:
單體架構(gòu)的應(yīng)用比較容易部署、測(cè)試,在項(xiàng)目的初期,單體應(yīng)用可以很好地運(yùn)行。然而,隨著需求的不斷增加,越來(lái)越多的人加入開(kāi)發(fā)團(tuán)隊(duì),代碼庫(kù)也在飛速地膨脹。慢慢地,單體應(yīng)用變得越來(lái)越臃腫,可維護(hù)性、靈活性逐漸降低,維護(hù)成本越來(lái)越高。
下面是單體架構(gòu)應(yīng)用的一些缺點(diǎn):
- 復(fù)雜性高:以一個(gè)百萬(wàn)行級(jí)別的單體應(yīng)用為例,整個(gè)項(xiàng)目包含的模塊非常多、模塊的邊界模糊、依賴關(guān)系不清晰、代碼質(zhì)量參差不齊、混亂地堆砌在一起。可想而知整個(gè)項(xiàng)目非常復(fù)雜。每次修改代碼都心驚膽戰(zhàn),甚至添加一個(gè)簡(jiǎn)單的功能,或者修改一個(gè)Bug都會(huì)帶來(lái)隱含的缺陷。
- 技術(shù)債務(wù):隨著時(shí)間推移、需求變更和人員更迭,會(huì)逐漸形成應(yīng)用程序的技術(shù)債務(wù),并且越積越多。“不壞不修”,這在軟件開(kāi)發(fā)中非常常見(jiàn),在單體應(yīng)用中這種思想更甚。已使用的系統(tǒng)設(shè)計(jì)或代碼難以被修改,因?yàn)閼?yīng)用程序中的其他模塊可能會(huì)以意料之外的方式使用它。
- 部署頻率低:隨著代碼的增多,構(gòu)建和部署的時(shí)間也會(huì)增加。而在單體應(yīng)用中,每次功能的變更或缺陷的修復(fù)都會(huì)導(dǎo)致需要重新部署整個(gè)應(yīng)用。全量部署的方式耗時(shí)長(zhǎng)、影響范圍大、風(fēng)險(xiǎn)高,這使得單體應(yīng)用項(xiàng)目上線部署的頻率較低。而部署頻率低又導(dǎo)致兩次發(fā)布之間會(huì)有大量的功能變更和缺陷修復(fù),出錯(cuò)率比較高。
- 可靠性差:某個(gè)應(yīng)用Bug,例如死循環(huán)、內(nèi)存溢出等,可能會(huì)導(dǎo)致整個(gè)應(yīng)用的崩潰。
- 擴(kuò)展能力受限:?jiǎn)误w應(yīng)用只能作為一個(gè)整體進(jìn)行擴(kuò)展,無(wú)法根據(jù)業(yè)務(wù)模塊的需要進(jìn)行伸縮。例如,應(yīng)用中有的模塊是計(jì)算密集型的,它需要強(qiáng)勁的CPU;有的模塊則是IO密集型的,需要更大的內(nèi)存。由于這些模塊部署在一起,不得不在硬件的選擇上做出妥協(xié)。
- 阻礙技術(shù)創(chuàng)新:?jiǎn)误w應(yīng)用往往使用統(tǒng)一的技術(shù)平臺(tái)或方案解決所有的問(wèn)題,團(tuán)隊(duì)中的每個(gè)成員都必須使用相同的開(kāi)發(fā)語(yǔ)言和框架,要想引入新框架或新技術(shù)平臺(tái)會(huì)非常困難。
二、分布式應(yīng)用
- 大型互聯(lián)網(wǎng)架構(gòu)演進(jìn)過(guò)程
- 架構(gòu)師應(yīng)具備的分布式知識(shí)
- 主流分布式架構(gòu)設(shè)計(jì)詳解
中級(jí)架構(gòu),分布式應(yīng)用,中間層分布式+數(shù)據(jù)庫(kù)分布式,是單體架構(gòu)的并發(fā)擴(kuò)展,將一個(gè)大的系統(tǒng)劃分為多個(gè)業(yè)務(wù)模塊,業(yè)務(wù)模塊分別部署在不同的服務(wù)器上,各個(gè)業(yè)務(wù)模塊之間通過(guò)接口進(jìn)行數(shù)據(jù)交互。數(shù)據(jù)庫(kù)也大量采用分布式數(shù)據(jù)庫(kù),如redis、ES、solor等。通過(guò)LVS/Nginx代理應(yīng)用,將用戶請(qǐng)求均衡的負(fù)載到不同的服務(wù)器上。其架構(gòu)圖如下所示:
該架構(gòu)相對(duì)于單體架構(gòu)來(lái)說(shuō),這種架構(gòu)提供了負(fù)載均衡的能力,大大提高了系統(tǒng)負(fù)載能力,解決了網(wǎng)站高并發(fā)的需求。另外還有以下特點(diǎn):
- 降低了耦合度:把模塊拆分,使用接口通信,降低模塊之間的耦合度。
- 責(zé)任清晰:把項(xiàng)目拆分成若干個(gè)子項(xiàng)目,不同的團(tuán)隊(duì)負(fù)責(zé)不同的子項(xiàng)目。
- 擴(kuò)展方便:增加功能時(shí)只需要再增加一個(gè)子項(xiàng)目,調(diào)用其他系統(tǒng)的接口就可以。
- 部署方便:可以靈活的進(jìn)行分布式部署。
- 提高代碼的復(fù)用性:比如service層,如果不采用分布式rest服務(wù)方式架構(gòu)就會(huì)在手機(jī)wap商城,微信商城,pc,android,ios每個(gè)端都要寫一個(gè)service層邏輯,開(kāi)發(fā)量大,難以維護(hù)一起升級(jí),這時(shí)候就可以采用分布式rest服務(wù)方式,公用一個(gè)service層。
缺點(diǎn):系統(tǒng)之間的交互要使用遠(yuǎn)程通信,接口開(kāi)發(fā)增大工作量,但是利大于弊。
三、微服務(wù)架構(gòu)
- 服務(wù)的前世今生
- 基于分布式思想下的RPC解決方案
- Dubbo應(yīng)用及源碼解讀
- SpringBoot
- SpringCloud應(yīng)用及源碼解讀
- Docker虛擬化技術(shù)
微服務(wù)架構(gòu),主要是中間層分解,將系統(tǒng)拆分成很多小應(yīng)用(微服務(wù)),微服務(wù)可以部署在不同的服務(wù)器上,也可以部署在相同的服務(wù)器不同的容器上。當(dāng)應(yīng)用的故障不會(huì)影響到其他應(yīng)用,單應(yīng)用的負(fù)載也不會(huì)影響到其他應(yīng)用,其代表框架有Springcloud、Dubbo等。其架構(gòu)圖如下所示:
- 易于開(kāi)發(fā)和維護(hù):一個(gè)微服務(wù)只會(huì)關(guān)注一個(gè)特定的業(yè)務(wù)功能,所以它業(yè)務(wù)清晰、代碼量較少。開(kāi)發(fā)和維護(hù)單個(gè)微服務(wù)相對(duì)簡(jiǎn)單。而整個(gè)應(yīng)用是由若干個(gè)微服務(wù)構(gòu)建而成的,所以整個(gè)應(yīng)用也會(huì)被維持在一個(gè)可控狀態(tài)。
- 單個(gè)微服務(wù)啟動(dòng)較快:?jiǎn)蝹€(gè)微服務(wù)代碼量較少,所以啟動(dòng)會(huì)比較快。
- 局部修改容易部署:?jiǎn)误w應(yīng)用只要有修改,就得重新部署整個(gè)應(yīng)用,微服務(wù)解決了這樣的問(wèn)題。一般來(lái)說(shuō),對(duì)某個(gè)微服務(wù)進(jìn)行修改,只需要重新部署這個(gè)服務(wù)即可。
- 技術(shù)棧不受限:在微服務(wù)架構(gòu)中,可以結(jié)合項(xiàng)目業(yè)務(wù)及團(tuán)隊(duì)的特點(diǎn),合理地選擇技術(shù)棧。例如某些服務(wù)可使用關(guān)系型數(shù)據(jù)庫(kù)MySQL;某些微服務(wù)有圖形計(jì)算的需求,可以使用Neo4j;甚至可根據(jù)需要,部分微服務(wù)使用Java開(kāi)發(fā),部分微服務(wù)使用Node.js開(kāi)發(fā)。
- 微服務(wù)雖然有很多吸引人的地方,但它并不是免費(fèi)的午餐,使用它是有代價(jià)的。使用微服務(wù)架構(gòu)面臨的挑戰(zhàn)。
- 運(yùn)維要求較高:更多的服務(wù)意味著更多的運(yùn)維投入。在單體架構(gòu)中,只需要保證一個(gè)應(yīng)用的正常運(yùn)行。而在微服務(wù)中,需要保證幾十甚至幾百個(gè)服務(wù)服務(wù)的正常運(yùn)行與協(xié)作,這給運(yùn)維帶來(lái)了很大的挑戰(zhàn)。
- 分布式固有的復(fù)雜性:使用微服務(wù)構(gòu)建的是分布式系統(tǒng)。對(duì)于一個(gè)分布式系統(tǒng),系統(tǒng)容錯(cuò)、網(wǎng)絡(luò)延遲、分布式事務(wù)等都會(huì)帶來(lái)巨大的挑戰(zhàn)。
- 接口調(diào)整成本高:微服務(wù)之間通過(guò)接口進(jìn)行通信。如果修改某一個(gè)微服務(wù)的API,可能所有使用了該接口的微服務(wù)都需要做調(diào)整。
- 重復(fù)勞動(dòng):很多服務(wù)可能都會(huì)使用到相同的功能,而這個(gè)功能并沒(méi)有達(dá)到分解為一個(gè)微服務(wù)的程度,這個(gè)時(shí)候,可能各個(gè)服務(wù)都會(huì)開(kāi)發(fā)這一功能,從而導(dǎo)致代碼重復(fù)。盡管可以使用共享庫(kù)來(lái)解決這個(gè)問(wèn)題(例如可以將這個(gè)功能封裝成公共組件,需要該功能的微服務(wù)引用該組件),但共享庫(kù)在多語(yǔ)言環(huán)境下就不一定行得通了。
四、Serverless架構(gòu)
當(dāng)我們還在容器的浪潮中前行時(shí),已經(jīng)有一些革命先驅(qū)悄然布局另外一個(gè)云計(jì)算戰(zhàn)場(chǎng):Serverless架構(gòu)。
2014年11月14日,亞馬遜AWS發(fā)布了新產(chǎn)品Lambda。當(dāng)時(shí)Lambda被描述為:一種計(jì)算服務(wù),根據(jù)時(shí)間運(yùn)行用戶的代碼,無(wú)需關(guān)心底層的計(jì)算資源。從某種意義上來(lái)說(shuō),Lambda姍姍來(lái)遲,它像云計(jì)算的PaaS理念:客戶只管業(yè)務(wù),無(wú)需擔(dān)心存儲(chǔ)和計(jì)算資源。
在此前不久,2014年10月22日,谷歌收購(gòu)了實(shí)時(shí)后端數(shù)據(jù)庫(kù)創(chuàng)業(yè)公司Firebase。Firebase聲稱開(kāi)發(fā)者只需引用一個(gè)API庫(kù)文件就可以使用標(biāo)準(zhǔn)RESTAPI的各種接口對(duì)數(shù)據(jù)進(jìn)行讀寫操作,只需編寫HTML+CSS+JavaScrip前端代碼,不需要服務(wù)器端代碼(如需整合,也極其簡(jiǎn)單)。相對(duì)于上兩者,F(xiàn)acebook在2014年二月收購(gòu)的Parse,則側(cè)重于提供一個(gè)通用的后臺(tái)服務(wù)。這些服務(wù)被稱為Serverless或nosever。想到PaaS(平臺(tái)即服務(wù))了是嗎?很像,用戶不需要關(guān)心基礎(chǔ)設(shè)施,只需要關(guān)心業(yè)務(wù),這是遲到的PaaS,也是更實(shí)用的PaaS。這很有可能將會(huì)變革整個(gè)開(kāi)發(fā)過(guò)程和傳統(tǒng)的應(yīng)用生命周期,一旦開(kāi)發(fā)者們習(xí)慣了這種全自動(dòng)的云上資源的創(chuàng)建和分配,或許就再也回不到那些需要微應(yīng)用配置資源的時(shí)代里去了。
對(duì)于Serverless架構(gòu),沒(méi)有全部展示出來(lái),那如果有感興趣了解的老友們呢...可以去我的主頁(yè),私信我【架構(gòu)】獲取,喜歡我的分布式、微服務(wù)系統(tǒng)圖的也能分享給大家~我對(duì)架構(gòu)體系做了一系列的系統(tǒng)圖,很開(kāi)心能分享給大家!