前后端分離模式概述

2021-01-29    分類: 網(wǎng)站建設(shè)

1、背景

前后端分離已成為互聯(lián)網(wǎng)項(xiàng)目開(kāi)發(fā)的業(yè)界標(biāo)準(zhǔn)使用方式,通過(guò)nginx+tomcat的方式(也可以中間加一個(gè)nodejs)有效的進(jìn)行解耦,并且前后端分離會(huì)為以后的大型分布式架構(gòu)、彈性計(jì)算架構(gòu)、微服務(wù)架構(gòu)、多端化服務(wù)(多種客戶端,例如:瀏覽器,車載終端,安卓,IOS等等)打下堅(jiān)實(shí)的基礎(chǔ)。這個(gè)步驟是系統(tǒng)架構(gòu)從猿進(jìn)化成人的必經(jīng)之路。

核心思想是前端HTML頁(yè)面通過(guò)AJAX調(diào)用后端的RESTFUL API接口并使用JSON數(shù)據(jù)進(jìn)行交互。

  • Web服務(wù)器:一般指像Nginx,Apache這類的服務(wù)器,他們一般只能解析靜態(tài)資源;
  • 應(yīng)用服務(wù)器:一般指像Tomcat,Jetty,Resin這類的服務(wù)器可以解析動(dòng)態(tài)資源也可以解析靜態(tài)資源,但解析靜態(tài)資源的能力沒(méi)有web服務(wù)器好;

一般都是只有web服務(wù)器才能被外網(wǎng)訪問(wèn),應(yīng)用服務(wù)器只能內(nèi)網(wǎng)訪問(wèn)。

以前的Java Web項(xiàng)目大多數(shù)都是Java程序員又當(dāng)?shù)之?dāng)媽,又搞前端,又搞后端。隨著時(shí)代的發(fā)展,漸漸的許多大中小公司開(kāi)始把前后端的界限分的越來(lái)越明確,前端工程師只管前端的事情,后端工程師只管后端的事情。正所謂術(shù)業(yè)有專攻,一個(gè)人如果什么都會(huì),那么他畢竟什么都不精。大中型公司需要專業(yè)人才,小公司需要全才,但是對(duì)于個(gè)人職業(yè)發(fā)展來(lái)說(shuō),前后端需要分離。

2、未分離時(shí)代(各種耦合)

早期主要使用MVC框架,Jsp+Servlet的結(jié)構(gòu)圖如下:



大致就是所有的請(qǐng)求都被發(fā)送給作為控制器的Servlet,它接受請(qǐng)求,并根據(jù)請(qǐng)求信息將它們分發(fā)給適當(dāng)?shù)腏SP來(lái)響應(yīng)。同時(shí),Servlet還根據(jù)JSP的需求生成JavaBeans的實(shí)例并輸出給JSP環(huán)境。JSP可以通過(guò)直接調(diào)用方法或使用UseBean的自定義標(biāo)簽得到JavaBeans中的數(shù)據(jù)。

需要說(shuō)明的是,這個(gè)View還可以采用 Velocity、Freemaker 等模板引擎。使用了這些模板引擎,可以使得開(kāi)發(fā)過(guò)程中的人員分工更加明確,還能提高開(kāi)發(fā)效率。

那么,在這個(gè)時(shí)期,開(kāi)發(fā)方式有如下兩種:

方式一



方式二



方式二已經(jīng)逐漸淘汰。主要原因有兩點(diǎn):

  • 前端在開(kāi)發(fā)過(guò)程中嚴(yán)重依賴后端,在后端沒(méi)有完成的情況下,前端根本無(wú)法干活;
  • 由于趨勢(shì)問(wèn)題,會(huì)JSP,懂velocity,freemarker等模板引擎的前端越來(lái)越少;

因此,方式二逐漸不被采用。然而,不得不說(shuō)一點(diǎn),方式一,其實(shí)很多小型傳統(tǒng)軟件公司至今還在使用。那么,方式一和方式二具有哪些共同的缺點(diǎn)呢?

1、前端無(wú)法單獨(dú)調(diào)試,開(kāi)發(fā)效率低;

2、前端不可避免會(huì)遇到后臺(tái)代碼,例如:

<body>
 <%
 request.setCharacterEncoding("utf-8")
 String name=request.getParameter("username");
 out.print(name);
 %>
</body>

這種方式耦合性太強(qiáng)。那么,就算你用了freemarker等模板引擎,不能寫(xiě)Java代碼。那前端也不可避免的要去重新學(xué)習(xí)該模板引擎的模板語(yǔ)法,無(wú)謂增加了前端的學(xué)習(xí)成本。正如我們后端開(kāi)發(fā)不想寫(xiě)前端一樣,你想想如果你的后臺(tái)代碼里嵌入前端代碼,你是什么感受?因此,這種方式十分不妥。

3、JSP本身所導(dǎo)致的一些其他問(wèn)題 比如,JSP第一次運(yùn)行的時(shí)候比較緩慢,因?yàn)槔镱^包含一個(gè)將JSP翻譯為Servlet的步驟。再比如因?yàn)橥郊虞d的原因,在JSP中有很多內(nèi)容的情況下,頁(yè)面響應(yīng)會(huì)很慢。

3、半分離時(shí)代

前后端半分離,前端負(fù)責(zé)開(kāi)發(fā)頁(yè)面,通過(guò)接口(Ajax)獲取數(shù)據(jù),采用Dom操作對(duì)頁(yè)面進(jìn)行數(shù)據(jù)綁定,最終是由前端把頁(yè)面渲染出來(lái)。這也就是Ajax與SPA應(yīng)用(單頁(yè)應(yīng)用)結(jié)合的方式,其結(jié)構(gòu)圖如下:



步驟如下:

  • 瀏覽器請(qǐng)求,CDN返回HTML頁(yè)面;
  • HTML中的JS代碼以Ajax方式請(qǐng)求后臺(tái)的Restful接口;
  • 接口返回Json數(shù)據(jù),頁(yè)面解析Json數(shù)據(jù),通過(guò)Dom操作渲染頁(yè)面;

后端提供的都是以JSON為數(shù)據(jù)格式的API接口供Native端使用,同樣提供給WEB的也是JSON格式的API接口。

那么意味著WEB工作流程是:

  • 打開(kāi)web,加載基本資源,如CSS,JS等;
  • 發(fā)起一個(gè)Ajax請(qǐng)求再到服務(wù)端請(qǐng)求數(shù)據(jù),同時(shí)展示loading;
  • 得到j(luò)son格式的數(shù)據(jù)后再根據(jù)邏輯選擇模板渲染出DOM字符串;
  • 將DOM字符串插入頁(yè)面中web view渲染出DOM結(jié)構(gòu);

這些步驟都由用戶所使用的設(shè)備中逐步執(zhí)行,也就是說(shuō)用戶的設(shè)備性能與APP的運(yùn)行速度聯(lián)系的更緊換句話說(shuō)就是如果用戶的設(shè)備很低端,那么APP打開(kāi)頁(yè)面的速度會(huì)越慢。

為什么說(shuō)是半分離的?因?yàn)椴皇撬许?yè)面都是單頁(yè)面應(yīng)用,在多頁(yè)面應(yīng)用的情況下,前端因?yàn)闆](méi)有掌握controller層,前端需要跟后端討論,我們這個(gè)頁(yè)面是要同步輸出呢,還是異步Json渲染呢?而且,即使在這一時(shí)期,通常也是一個(gè)工程師搞定前后端所有工作。因此,在這一階段,只能算半分離。

首先,這種方式的優(yōu)點(diǎn)是很明顯的。前端不會(huì)嵌入任何后臺(tái)代碼,前端專注于HTML、CSS、JS的開(kāi)發(fā),不依賴于后端。自己還能夠模擬Json數(shù)據(jù)來(lái)渲染頁(yè)面。發(fā)現(xiàn)Bug,也能迅速定位出是誰(shuí)的問(wèn)題。

然而,在這種架構(gòu)下,還是存在明顯的弊端的。最明顯的有如下幾點(diǎn):

  • JS存在大量冗余,在業(yè)務(wù)復(fù)雜的情況下,頁(yè)面的渲染部分的代碼,非常復(fù)雜;
  • 在Json返回的數(shù)據(jù)量比較大的情況下,渲染的十分緩慢,會(huì)出現(xiàn)頁(yè)面卡頓的情況;
  • SEO( Search Engine Optimization,即搜索引擎優(yōu)化)非常不方便,由于搜索引擎的爬蟲(chóng)無(wú)法爬下JS異步渲染的數(shù)據(jù),導(dǎo)致這樣的頁(yè)面,SEO會(huì)存在一定的問(wèn)題;
  • 資源消耗嚴(yán)重,在業(yè)務(wù)復(fù)雜的情況下,一個(gè)頁(yè)面可能要發(fā)起多次HTTP請(qǐng)求才能將頁(yè)面渲染完畢??赡苡腥瞬环?,覺(jué)得PC端建立多次HTTP請(qǐng)求也沒(méi)啥。那你考慮過(guò)移動(dòng)端么,知道移動(dòng)端建立一次HTTP請(qǐng)求需要消耗多少資源么?

正是因?yàn)槿缟先秉c(diǎn),我們才亟需真正的前后端分離架構(gòu)。

4、分離時(shí)代

在前后端徹底分離這一時(shí)期,前端的范圍被擴(kuò)展,controller層也被認(rèn)為屬于前端的一部分。在這一時(shí)期:

  • 前端:負(fù)責(zé)View和Controller層。
  • 后端:只負(fù)責(zé)Model層,業(yè)務(wù)/數(shù)據(jù)處理等。

可是服務(wù)端人員對(duì)前端HTML結(jié)構(gòu)不熟悉,前端也不懂后臺(tái)代碼呀,controller層如何實(shí)現(xiàn)呢?這就是node.js的妙用了,node.js適合運(yùn)用在高并發(fā)、I/O密集、少量業(yè)務(wù)邏輯的場(chǎng)景。最重要的一點(diǎn)是,前端不用再學(xué)一門(mén)其他的語(yǔ)言了,對(duì)前端來(lái)說(shuō),上手度大大提高。



可以就把Nodejs當(dāng)成跟前端交互的api。總得來(lái)說(shuō),Nodejs的作用在mvc中相當(dāng)于C(控制器)。Nodejs路由的實(shí)現(xiàn)邏輯是把前端靜態(tài)頁(yè)面代碼當(dāng)成字符串發(fā)送到客戶端(例如瀏覽器),簡(jiǎn)單理解可以理解為路由是提供給客戶端的一組api接口,只不過(guò)返回的數(shù)據(jù)是頁(yè)面代碼的字符串而已。

用NodeJs來(lái)作為橋梁架接服務(wù)器端API輸出的JSON。后端出于性能和別的原因,提供的接口所返回的數(shù)據(jù)格式也許不太適合前端直接使用,前端所需的排序功能、篩選功能,以及到了視圖層的頁(yè)面展現(xiàn),也許都需要對(duì)接口所提供的數(shù)據(jù)進(jìn)行二次處理。這些處理雖可以放在前端來(lái)進(jìn)行,但也許數(shù)據(jù)量一大便會(huì)浪費(fèi)瀏覽器性能。因而現(xiàn)今,增加Node中間層便是一種良好的解決方案。


瀏覽器(webview)不再直接請(qǐng)求JSP的API,而是:

  • 瀏覽器請(qǐng)求服務(wù)器端的NodeJS;
  • NodeJS再發(fā)起HTTP去請(qǐng)求JSP;
  • JSP依然原樣API輸出JSON給NodeJS;
  • NodeJS收到JSON后再渲染出HTML頁(yè)面;
  • NodeJS直接將HTML頁(yè)面flush到瀏覽器;

這樣,瀏覽器得到的就是普通的HTML頁(yè)面,而不用再發(fā)Ajax去請(qǐng)求服務(wù)器了。

淘寶的前端團(tuán)隊(duì)提出的中途島(Midway Framework)的架構(gòu)如下圖所示:


增加node.js作為中間層,具體有哪些好處呢?

1、適配性提升;我們其實(shí)在開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)給PC端、mobile、app端各自研發(fā)一套前端。其實(shí)對(duì)于這三端來(lái)說(shuō),大部分端業(yè)務(wù)邏輯是一樣的。唯一區(qū)別就是交互展現(xiàn)邏輯不同。

如果controller層在后端手里,后端為了這些不同端頁(yè)面展示邏輯,自己維護(hù)這些controller,模版無(wú)法重用,徒增和前端溝通端成本。 如果增加了node.js層,此時(shí)架構(gòu)圖如下:



在該結(jié)構(gòu)下,每種前端的界面展示邏輯由node層自己維護(hù)。如果產(chǎn)品經(jīng)理中途想要改動(dòng)界面什么的,可以由前端自己專職維護(hù),后端無(wú)需操心。前后端各司其職,后端專注自己的業(yè)務(wù)邏輯開(kāi)發(fā),前端專注產(chǎn)品效果開(kāi)發(fā)。

2、響應(yīng)速度提升;我們有時(shí)候,會(huì)遇到后端返回給前端的數(shù)據(jù)太簡(jiǎn)單了,前端需要對(duì)這些數(shù)據(jù)進(jìn)行邏輯運(yùn)算。那么在數(shù)據(jù)量比較小的時(shí)候,對(duì)其做運(yùn)算分組等操作,并無(wú)影響。但是當(dāng)數(shù)據(jù)量大的時(shí)候,會(huì)有明顯的卡頓效果。這時(shí)候,node中間層其實(shí)可以將很多這樣的代碼放入node層處理、也可以替后端分擔(dān)一些簡(jiǎn)單的邏輯、又可以用模板引擎自己掌握前臺(tái)的輸出。這樣做靈活度、響應(yīng)度都大大提升。

3、性能得到提升;大家應(yīng)該都知道單一職責(zé)原則。從該角度來(lái)看,我們,請(qǐng)求一個(gè)頁(yè)面,可能要響應(yīng)很多個(gè)后端接口,請(qǐng)求變多了,自然速度就變慢了,這種現(xiàn)象在mobile端更加嚴(yán)重。采用node作為中間層,將頁(yè)面所需要的多個(gè)后端數(shù)據(jù),直接在內(nèi)網(wǎng)階段就拼裝好,再統(tǒng)一返回給前端,會(huì)得到更好的性能。

4、異步與模板統(tǒng)一;淘寶首頁(yè)就是被幾十個(gè)HTML片段(每個(gè)片段一個(gè)文件)拼裝成,之前PHP同步include這幾十個(gè)片段,一定是串行的,Node可以異步,讀文件可以并行,一旦這些片段中也包含業(yè)務(wù)邏輯,異步的優(yōu)勢(shì)就很明顯了,真正做到哪個(gè)文件先渲染完就先輸出顯示。

前端機(jī)的文件系統(tǒng)越復(fù)雜,頁(yè)面的組成片段越多,這種異步的提速效果就越明顯。前后端模板統(tǒng)一在無(wú)線領(lǐng)域很有用,PC頁(yè)面和WIFI場(chǎng)景下的頁(yè)面適合前端渲染(后端數(shù)據(jù)Ajax到前端),2G、3G弱網(wǎng)絡(luò)環(huán)境適合后端渲染(數(shù)據(jù)隨頁(yè)面吐給前端),所以同樣的模板,在不同的條件下走不同的渲染渠道,模板只需一次開(kāi)發(fā)。

增加NodeJS中間層后的前后端職責(zé)劃分:


5、總結(jié)

從經(jīng)典的JSP+Servlet+JavaBean的MVC時(shí)代,到SSM(Spring + SpringMVC + Mybatis)和SSH(Spring + Struts + Hibernate)的Java 框架時(shí)代,再到前端框架(KnockoutJS、AngularJS、vueJS、ReactJS)為主的MV*時(shí)代,然后是Nodejs引領(lǐng)的全棧時(shí)代,技術(shù)和架構(gòu)一直都在進(jìn)步。雖然“基于NodeJS的全棧式開(kāi)發(fā)”模式很讓人興奮,但是把基于Node的全棧開(kāi)發(fā)變成一個(gè)穩(wěn)定,讓大家都能接受的東西還有很多路要走。

創(chuàng)新之路不會(huì)止步,無(wú)論是前后端分離模式還是其他模式,都是為了更方便得解決需求,但它們都只是一個(gè)“中轉(zhuǎn)站”。前端項(xiàng)目與后端項(xiàng)目是兩個(gè)項(xiàng)目,放在兩個(gè)不同的服務(wù)器,需要獨(dú)立部署,兩個(gè)不同的工程,兩個(gè)不同的代碼庫(kù),不同的開(kāi)發(fā)人員。前端只需要關(guān)注頁(yè)面的樣式與動(dòng)態(tài)數(shù)據(jù)的解析及渲染,而后端專注于具體業(yè)務(wù)邏輯。

分享文章:前后端分離模式概述
當(dāng)前地址:http://www.muchs.cn/news19/98019.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、自適應(yīng)網(wǎng)站搜索引擎優(yōu)化網(wǎng)站策劃、電子商務(wù)、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)