本文系轉(zhuǎn)載,原作者,普元,敖顯奇
轉(zhuǎn)載本文需保留此處版權(quán)聲明:本文版權(quán)屬于EAII企業(yè)架構(gòu)創(chuàng)新研究院(微信號(hào):eaworld),違者必究。
一、被誤解的前后端分離
在Web應(yīng)用開發(fā)過程中,業(yè)界對(duì)前后端的分界線似乎一直都沒有確定的概念,不過大多數(shù)人以瀏覽器作為前后端的分界線。將瀏覽器中為用戶進(jìn)行頁面展示的部分稱為前端,而將運(yùn)行于服務(wù)器,為前端提供業(yè)務(wù)邏輯和數(shù)據(jù)準(zhǔn)備的所有代碼統(tǒng)稱為后端。
雖然前后端分離在數(shù)年前就已經(jīng)開始受到關(guān)注,但很多人對(duì)它卻是只聞其聲,未見其形,所以對(duì)它產(chǎn)生了一些誤解,誤以為前后段分離只是一種Web應(yīng)用的開發(fā)模式,只要在Web應(yīng)用的開發(fā)期進(jìn)行了前后端開發(fā)工作的分工就是前后端分離。
其實(shí)并非如此,
準(zhǔn)確的說,前后端分離并不只是開發(fā)模式,而是Web應(yīng)用的一種架構(gòu)模式
。在開發(fā)期,前后端工程師可以通過約定好交互接口,實(shí)現(xiàn)并行開發(fā);在運(yùn)行期,前后端分離模式需要對(duì)Web應(yīng)用進(jìn)行分離部署,前后端之間使用HTTP請(qǐng)求進(jìn)行交互。然而作為應(yīng)用的架構(gòu)模式,前后端分離并不是通過這樣一句話就能一概而談的,我們可以從交互形式、代碼組織方式、開發(fā)模式三個(gè)方面對(duì)前后端分離進(jìn)行認(rèn)識(shí)。
1、交互形式
在前后端分離架構(gòu)中,后端只需要負(fù)責(zé)按照約定的數(shù)據(jù)格式向前端提供可調(diào)用的API服務(wù)即可。前后端之間通過HTTP請(qǐng)求進(jìn)行交互,前端獲取到數(shù)據(jù)后,進(jìn)行頁面的裝配和渲染。
2、代碼組織方式
在傳統(tǒng)架構(gòu)模式中,前后端代碼存放于同一個(gè)代碼庫中,甚至是同一工程目錄下。頁面中還夾雜著后端代碼。前后端工程師進(jìn)行開發(fā)時(shí),都必須把整個(gè)項(xiàng)目導(dǎo)入到開發(fā)工具中。
而前后端分離模式在代碼組織形式上有以下兩種:
半分離
前后端共用一個(gè)代碼庫,但是代碼分別存放在兩個(gè)工程中。后端不關(guān)心或很少關(guān)心前端元素的輸出情況,前端不能獨(dú)立進(jìn)行開發(fā)和測試,項(xiàng)目中缺乏前后端交互的測試用例。
分離
前后端代碼庫分離,前端代碼中有可以進(jìn)行Mock測試(通過構(gòu)造虛擬測試對(duì)象以簡化測試環(huán)境的方法)的偽后端,能支持前端的獨(dú)立開發(fā)和測試。而后端代碼中除了功能實(shí)現(xiàn)外,還有著詳細(xì)的測試用例,以保證API的可用性,降低集成風(fēng)險(xiǎn)。
3、開發(fā)模式
傳統(tǒng)的MVC架構(gòu)開發(fā),沒有進(jìn)行前后端分離,前端工程師負(fù)責(zé)編寫HTML,完成前端頁面設(shè)計(jì),然后給后端工程師員套界面,使用模板技術(shù)將前端代碼轉(zhuǎn)換成JSP頁面,同時(shí)內(nèi)嵌java代碼。應(yīng)用運(yùn)行期,將全部代碼進(jìn)行打包,部署到同一服務(wù)器上,或者進(jìn)行簡單的動(dòng)靜態(tài)分離部署。
此時(shí),應(yīng)用的開發(fā)流程如下圖所示。
在前后端分離架構(gòu)中,前端工程師只需要編寫HTML、js、CSS等前端資源,然后通過HTTP請(qǐng)求調(diào)用后端提供的服務(wù)即可。除了開發(fā)期的分離,在運(yùn)行期前后端資源也會(huì)進(jìn)行分離部署。
前后端分離之后,開發(fā)流程將如下圖所示。
通過上面的兩幅流程圖,不難發(fā)現(xiàn),在開發(fā)模式上,前后段分離不僅僅只是工程師的分工開發(fā),更重要的意義在于實(shí)現(xiàn)了前后端的并行開發(fā),和簡化了開發(fā)流程。
二、為什么要“離”:4個(gè)好處
重新認(rèn)識(shí)前后端分離之后,想必大家心里都會(huì)有疑問,前后端分離模式與之前的Web應(yīng)用架構(gòu)相比可謂是大相徑庭,我們?yōu)槭裁匆M(jìn)行前后端分離呢?正如莎士比亞在《哈姆雷特》中的經(jīng)典名句一樣,分還是不分,這是個(gè)問題。
從目前應(yīng)用軟件的發(fā)展趨勢來看,一方面,用戶越來越注重軟件的體驗(yàn)感,隨著互聯(lián)網(wǎng)的蓬勃發(fā)展,應(yīng)用開始走向多終端化;另一方面,大型應(yīng)用的架構(gòu)模式正紛紛向著云化、微服務(wù)化發(fā)展。
雖然過去的應(yīng)用架構(gòu)暫時(shí)還能支撐起當(dāng)下應(yīng)用的開發(fā),但是各種弊端已經(jīng)開始浮出水面,幾年前能帶來開發(fā)便捷優(yōu)勢的前后端代碼混合模式,在當(dāng)下已經(jīng)成為了拖慢我們前進(jìn)步伐的泥沼,讓我們屢屢吃痛。我們之所以開始嘗試前后端分離,是為了能在未來獲得更好的發(fā)展,期望通過前后端分離架構(gòu),來為我們帶來以下4個(gè)方面的提升。
為孵化優(yōu)質(zhì)產(chǎn)品打造精益團(tuán)隊(duì)
正如康威定律所述,產(chǎn)品是組織溝通結(jié)構(gòu)的縮影,軟件開發(fā)團(tuán)隊(duì)想要孵化出優(yōu)質(zhì)的產(chǎn)品,必須先打造一個(gè)精益的開發(fā)團(tuán)隊(duì)。開發(fā)團(tuán)隊(duì)的組織劃分是如何影響產(chǎn)品的孵化呢,我們通過下面的示例來進(jìn)行說明。
如果開發(fā)團(tuán)隊(duì)是按照業(yè)務(wù)邊界進(jìn)行劃分的,開發(fā)出來的產(chǎn)品將可能會(huì)是微服務(wù)的架構(gòu)。
如果開發(fā)團(tuán)隊(duì)分為前端團(tuán)隊(duì)、后臺(tái)服務(wù)團(tuán)隊(duì)和DBA團(tuán)隊(duì),產(chǎn)品將會(huì)成長為下面的架構(gòu)。
應(yīng)用不斷迭代,功能日趨完善,開發(fā)團(tuán)隊(duì)也隨之壯大。雖然現(xiàn)在有些人比較推崇全棧工程師,一位全棧工程師就能支持前后端的所有開發(fā)。但是試想一下,如果在開發(fā)團(tuán)隊(duì)中前后端開發(fā)分隔不清,職責(zé)邊界模糊不明,代碼均由相同的工程師完成,長此以往前后端代碼的耦合程度可想而知。
通過將開發(fā)團(tuán)隊(duì)前后端分離化,讓前后端工程師只需要專注于前端或后端的開發(fā)工作,使得前后端工程師分別自治,培養(yǎng)其獨(dú)特的技術(shù)特性,然后構(gòu)建出一個(gè)全棧式的精益開發(fā)團(tuán)隊(duì)。這樣的開發(fā)團(tuán)隊(duì)能夠快速應(yīng)對(duì)需求的變更以及市場的復(fù)雜多變,打造出架構(gòu)清晰、前后端并重的優(yōu)質(zhì)產(chǎn)品。
提升開發(fā)效率
傳統(tǒng)開發(fā)模式中,前后端開發(fā)強(qiáng)依賴。需要前端工程師先完成靜態(tài)頁面的Demo,后端工程師才能將頁面Demo翻譯成VM模板,如果前端頁面出現(xiàn)變動(dòng),又會(huì)需要前后端工程師再走一次開發(fā)流程,如此一來開發(fā)效率將會(huì)變得很低。
前后端分離以后,可以實(shí)現(xiàn)前后端代碼的解耦,只要前后端溝通約定好應(yīng)用所需接口以及接口參數(shù),便可以開始并行開發(fā),無需等待對(duì)方的開發(fā)工作結(jié)束。與此同時(shí),即使需求發(fā)生變更,只要接口與數(shù)據(jù)格式不變,后端開發(fā)人員就不需要修改代碼,只要前端進(jìn)行變動(dòng)即可。如此一來整個(gè)應(yīng)用的開發(fā)效率必然會(huì)有質(zhì)的提升。
完美應(yīng)對(duì)復(fù)雜多變的前端需求
Web應(yīng)用的用戶體驗(yàn)關(guān)注度與日俱增,使得應(yīng)用的前端界面需要有華麗酷炫的外觀,簡單易用的操作,變化多樣的界面設(shè)計(jì)和個(gè)性化的自定義展示。這使得前端開始變重,邏輯復(fù)雜程度加大,渲染效果多樣化加劇。
移動(dòng)終端的大范圍普及,讓應(yīng)用向著多終端化發(fā)展,這就要求前端頁面需要對(duì)不同終端的顯示都能進(jìn)行配適。
傳統(tǒng)開發(fā)模式中,前后端工程師開發(fā)職責(zé)不明確,面對(duì)復(fù)雜多變的前端需求,開發(fā)團(tuán)隊(duì)勢必會(huì)變得捉襟見肘、不堪重負(fù)。
如果開發(fā)團(tuán)隊(duì)能完成前后端分離的轉(zhuǎn)型,打造優(yōu)秀的前后端團(tuán)隊(duì),開發(fā)獨(dú)立化,讓開發(fā)人員做到專注專精,開發(fā)能力必然會(huì)有所提升,能夠完美應(yīng)對(duì)各種復(fù)雜多變的前端需求。
增強(qiáng)代碼可維護(hù)性
前后端分離后,應(yīng)用的代碼不再是前后端混合,只有在運(yùn)行期才會(huì)有調(diào)用依賴關(guān)系。應(yīng)用代碼將會(huì)變得整潔清晰,不論是代碼閱讀還是代碼維護(hù)都會(huì)比以前輕松。
三、我要不要“離”:4種場景
然而任何一項(xiàng)技術(shù)都不是銀彈,前后端分離也是如此。雖然前后端分離架構(gòu)能帶來眾多優(yōu)勢,但終究得建立在開發(fā)團(tuán)隊(duì)適合的基礎(chǔ)之上。我們暫且以前端頁面的渲染效果與邏輯復(fù)雜程度把Web應(yīng)用大致分為輕前端、重前端、前后均衡三種類型,然后加上現(xiàn)在熱門的微服務(wù)架構(gòu)應(yīng)用,一起探討一下什么樣的Web應(yīng)用適合進(jìn)行前后端分離。
輕前端
頁面布局簡單,顏色、字體類型較少
對(duì)前端界面的渲染效果沒有高要求,無動(dòng)畫效果
只有少量、簡單的業(yè)務(wù)邏輯
只需要在不同終端上布局能適應(yīng)
對(duì)于這樣對(duì)前端渲染要求不高,業(yè)務(wù)邏輯簡單的輕前端應(yīng)用來說,因?yàn)樯婕暗降那岸思夹g(shù)并不復(fù)雜,所以沒必要追求前后端分離。將前后端代碼放到一起,反而更方便進(jìn)行開發(fā),但是在開發(fā)過程中需要做到關(guān)注點(diǎn)分離(Separate
Concern)。
重前端
頁面布局復(fù)雜,使用了多種顏色和字體
需要有較高的頁面渲染效果,有大量動(dòng)畫
前端頁面中包含有復(fù)雜業(yè)務(wù)邏輯
需要在不同終端和瀏覽器上保證布局適應(yīng)和渲染效果
對(duì)于重前端應(yīng)用,建議采用前后端分離架構(gòu),如果開發(fā)團(tuán)隊(duì)中前端工程師不足,需要盡早完善前端團(tuán)隊(duì)的建設(shè),確保前后端并重。
前后均衡
頁面布局適中,使用的顏色和字體種類不多
頁面中使用了少許動(dòng)畫效果
業(yè)務(wù)邏輯較為簡單,可下沉到后端實(shí)現(xiàn)
只需要在不同終端上布局能適應(yīng)
對(duì)于前后端均衡應(yīng)用,建議綜合團(tuán)隊(duì)的人員結(jié)構(gòu)和未來發(fā)展方向進(jìn)行考慮。如果在團(tuán)隊(duì)中前端工程師的占比不高,后續(xù)也沒有繼續(xù)發(fā)展前端的計(jì)劃,那么就不建議過于追求前后端分離。如果對(duì)未來有更高期望,即使在前端工程師占比不高的情況下,依然建議團(tuán)隊(duì)嘗試前后端分離轉(zhuǎn)型,開始著手培養(yǎng)合適的前端工程師。如果團(tuán)隊(duì)中已經(jīng)有了相當(dāng)規(guī)模的前端工程師,建議立即轉(zhuǎn)向前后端分離,并且盡早做到前后端代碼分離,為前端提供一個(gè)可以進(jìn)行開發(fā)調(diào)試的偽后端。
微服務(wù)架構(gòu)應(yīng)用
微服務(wù)架構(gòu)應(yīng)用由大量微服務(wù)提供者構(gòu)成,共同為用戶提供服務(wù)。在微服務(wù)架構(gòu)中,很多微服務(wù)提供者都是基于SpringBoot實(shí)現(xiàn)的,通過API
Getway(API網(wǎng)關(guān))進(jìn)行微服務(wù)的整合,然后在一個(gè)統(tǒng)一的前端門戶上為用戶提供所需服務(wù)。
微服務(wù)基于SpringBoot開發(fā),要達(dá)到快速交付的目的,并且每個(gè)微服務(wù)的粒度都比較小,這必然需要微服務(wù)的前后端由不同的工程師分別實(shí)現(xiàn),然后相互之間使用Restful進(jìn)行通訊。如果還是沿用之前的開發(fā)模式,將會(huì)增大微服務(wù)架構(gòu)應(yīng)用的構(gòu)建難度。而前后段分離模式正是解決這一難題的良藥。
四、分離部署方案淺析
前后端開發(fā)分離之后,應(yīng)用在部署時(shí)也需要進(jìn)行前后端分離。在進(jìn)行前后端分離方案選擇的時(shí)候,需要結(jié)合項(xiàng)目的需求情況和用戶群體來考慮。目前業(yè)內(nèi)較為常用的前后端分離部署方案有如下幾種。
1、Nginx+Server
將前端資源部署在Nginx上,后端服務(wù)部署在常規(guī)的服務(wù)器。當(dāng)瀏覽器發(fā)起訪問請(qǐng)求的時(shí)候,如果請(qǐng)求的是頁面資源,Nginx直接把資源返回到前端;如果請(qǐng)求是調(diào)用后端服務(wù),則經(jīng)過Nginx轉(zhuǎn)發(fā)到后端服務(wù)器,完成響應(yīng)后經(jīng)Nginx返回到瀏覽器。
這個(gè)方案比較簡單,易于實(shí)現(xiàn),而且能達(dá)到前后端解耦的目的。
但是對(duì)于頁面量比較大,需要有良好SEO的應(yīng)用來說,此方案缺點(diǎn)也較為明顯。因?yàn)镹ginx只是向?yàn)g覽器返回頁面靜態(tài)資源,而國內(nèi)的搜索引擎爬蟲只會(huì)抓取靜態(tài)數(shù)據(jù),不會(huì)解析頁面中的js,這使得應(yīng)用得不到良好的搜索引擎支持。同時(shí)因?yàn)镹ginx不會(huì)進(jìn)行頁面的組裝渲染,需要把靜態(tài)頁面返回到瀏覽器,然后完成渲染工作,這加重了瀏覽器的渲染負(fù)擔(dān)。
2、Node+Server
這是淘寶所使用的前后端分離模式,在瀏覽器與后端服務(wù)器之間增加一個(gè)了Node Server作為中間層,將前端資源部署到Node Server中。Node
Server中還包含了一層Model Proxy,負(fù)責(zé)與服務(wù)端進(jìn)行通信。
瀏覽器發(fā)出的請(qǐng)求都被Node Server接收,然后通過Model Proxy調(diào)用后端服務(wù)器提供的服務(wù)。Node
Server得到后端服務(wù)器反饋,接著在Node Server中完成頁面的組裝渲染,把最終頁面返回給瀏覽器。
如此一來不僅達(dá)到了前后端解耦的目的,還解決了瀏覽器渲染負(fù)擔(dān)過重的問題,為SEO提供了比較好的支持。
但在這樣的模式中,瀏覽器所有發(fā)出的請(qǐng)求都需要經(jīng)過Node
Server進(jìn)行中轉(zhuǎn),然后才能到達(dá)后端服務(wù)器。在實(shí)際的應(yīng)用中,并不是所有的請(qǐng)求都需要頁面渲染,只要在頁面上直接調(diào)用后端服務(wù)器提供的服務(wù)即可。所以這個(gè)模式必然會(huì)對(duì)請(qǐng)求性能有所消耗
3、Nginx+Node+Server
為了能解決方案2中請(qǐng)求性能損失的問題,我們可以考慮在其基礎(chǔ)之上增加Nginx。瀏覽器發(fā)起的請(qǐng)求經(jīng)過Nginx進(jìn)行分發(fā),URL請(qǐng)求統(tǒng)一分發(fā)到Node
Server,在Node Server中進(jìn)行頁面組裝渲染;API請(qǐng)求則直接發(fā)送到后端服務(wù)器,完成響應(yīng)。
目前在已經(jīng)有一個(gè)名為Goku的Go語言框架提供了這樣的前后端分離解決方案。
通過對(duì)三種前后端分離方案的對(duì)比可以看出:
如果是企業(yè)級(jí)應(yīng)用,不需要考慮對(duì)SEO的支持,瀏覽器渲染也可以忽略不計(jì),Nginx+Server的模式無疑是最好的選擇,實(shí)施成本相對(duì)來說比較低;
如果是互聯(lián)網(wǎng)應(yīng)用,需要有良好的SEO支持,頁面渲染工作量大,那應(yīng)該選擇Nginx+Node+Server的方案,各個(gè)方面都能得到比較好的兼顧。
五、總結(jié)
前后端分離并非僅僅只是前后端開發(fā)的分工,而是在開發(fā)期進(jìn)行代碼存放分離、前后端開發(fā)職責(zé)分離,前后端能夠獨(dú)立進(jìn)行開發(fā)測試;在運(yùn)行期進(jìn)行應(yīng)用部署分離,前后端之間通過HTTP請(qǐng)求進(jìn)行通訊。前后端分離的開發(fā)模式與傳統(tǒng)模式相比,能為我們提升開發(fā)效率、增強(qiáng)代碼可維護(hù)性,讓我們有規(guī)劃地打造一個(gè)前后端并重的精益開發(fā)團(tuán)隊(duì),更好地應(yīng)對(duì)越來越復(fù)雜多變的Web應(yīng)用開發(fā)需求。
傳統(tǒng)的前后端混合開發(fā)模式,雖然久經(jīng)考驗(yàn),到現(xiàn)在依然還是能支撐起應(yīng)用的開發(fā)。但是放眼未來,應(yīng)用的云化、微服務(wù)化勢不可擋。同社會(huì)分工精細(xì)化一樣,前后端開發(fā)的精細(xì)化也是必然趨勢。技術(shù)在持續(xù)進(jìn)步,架構(gòu)在不斷演進(jìn),只有緊跟發(fā)展的腳步,不斷調(diào)整項(xiàng)目管理方式,軟件開發(fā)模式,才能在互聯(lián)網(wǎng)浪潮中把握機(jī)會(huì),乘風(fēng)破浪。
前后端分離,是為了讓彼此更好。
關(guān)于作者
敖顯奇
現(xiàn)任普元信息SOA產(chǎn)品部開發(fā)工程師,普元新一代數(shù)字化企業(yè)云平臺(tái)開發(fā)團(tuán)隊(duì)成員,參與云平臺(tái)中VCS、Portal Server領(lǐng)域系統(tǒng)開發(fā)。過去兩年中參與了普元
Platform產(chǎn)品 7.3~7.5版本以及快速流程實(shí)施框架等功能組件的開發(fā)。
關(guān)于EAII
EAII(Enterprise Architecture Innovation
Institute)企業(yè)架構(gòu)創(chuàng)新研究院,致力于軟件架構(gòu)創(chuàng)新與實(shí)踐,加速企業(yè)數(shù)字化轉(zhuǎn)型。