關於大型網站技術演進的思考(十四)--網站靜態化處理—先後端分離—上(6)

前文講到了CSI技術,這就說明網站靜態化技術的講述已經推動到了瀏覽器端了即真正到了web前端的範疇了,而時下web前端技術的前沿之一就是先後端分離技術了,那麼在這裏網站靜態化技術和先後端分離技術產生了交集,因此今天我將討論下先後端分離技術,先後端分離技術討論完後,下一篇文章我將會以網站靜態化技術的角度回過頭來從新審視下先後端分離技術,但願經過這種審視來加深咱們對兩套技術的理解。 php

  先後端分離技術我我的認爲是web前端被專業化之後的必由之路,而nodejs的出現是先後端分離技術的一個強興的催化劑,緣由是nodejs的出現削平了前端技術和服務端技術之間的鴻溝,使得先後端兩套不一樣技術體系進行真正意義的解耦提供了無限的可能性。可是若是咱們把nodejs技術的使用認爲就是實現了先後端分離,這種理解又實在太膚淺了,下面我將講講我研究過的先後端分離技術方案,以及這些技術方案隱藏在背後思考,但願這些思考能給你們以一個新的思路來理解先後端分離技術。 html

  咱們要深入理解先後端分離技術有一個重要的前提,那就是要把先後端分離技術認爲是傳統的web應用裏的MVC設計模式的進一步演進。那麼咱們首先來看看MVC的定義,下面的內容摘錄於維基百科的解釋,具體以下: 前端

MVC模式(Model-View-Controller)是軟件工程中的一種軟件架構模式,把軟件系統分爲三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。 java

 

MVC模式最先由Trygve Reenskaug在1978年提出[1] ,是施樂帕羅奧多研究中心(Xerox PARC)在20世紀80年代爲程序語言Smalltalk發明的一種軟件設計模式。MVC模式的目的是實現一種動態的程式設計,使後續對程序的修改和擴展簡化,而且使程序某一部分的重複利用成爲可能。除此以外,此模式經過對複雜度的簡化,使程序結構更加直觀。軟件系統經過對自身基本部分分離的同時也賦予了各個基本部分應有的功能。專業人員能夠經過自身的專長分組: node

 

(控制器 Controller)- 負責轉發請求,對請求進行處理。 程序員

 

(視圖 View) - 界面設計人員進行圖形界面設計。 web

 

(模型 Model) - 程序員編寫程序應有的功能(實現算法等等)、數據庫專家進行數據管理和數據庫設計(能夠實現具體的功能)。 算法

  各種用於Web應用開發的語言裏都有屬於本身的MVC框架,例如本人最熟悉的服務端語言java裏就有大名鼎鼎的struts2,springMVC的MVC應用框架,我早期從事java的web開發時候認爲這些MVC框架都是很是的博大精深,用途普遍,可是當我逐漸轉向了web前端技術開發之後又以爲這些框架的不少功能顯得那麼的多餘和累贅,所以我曾寫過一篇文章專門討論過這些問題,該文章的名字叫作《爲何作java的web開發咱們會使用struts2,springMVC和spring這樣的框架?》。 spring

  其實這篇文章被寫的源頭就是在於我認爲像struts2和springMVC這樣的框架作了太多瀏覽器自己就能夠完成的工做,例如:頁面的渲染操做,由於服務端搶了瀏覽器端的部分工做,這其實也就等於限制了web前端技術的深刻運用,像不少前端的優化技術以及不少提高用戶體驗的技術就很難派上用場,之因此產生這些問題,我認爲傳統的MVC框架本質實際上是一個服務端的MVC框架,雖然MVC設計模式裏的V即View視圖層是想把界面開發工做專業化,讓界面設計人員能專心於界面開發,可是傳統的MVC框架下的View層的本質倒是一個徹徹底底的服務端技術。 數據庫

  咱們以java的web開發裏jsp爲例,JSP全名爲Java Server Pages,中文名叫java服務器頁面,其根本是一個簡化的Servlet設計,它是java裏動態網頁的技術標準,這就說明jsp雖然看起來像html,其實它並非真正的html,它須要被java的web容器進行解析轉化爲瀏覽器能夠解析的html頁面,而後經過網絡傳輸到瀏覽器後,瀏覽器才能正確的展現這個jsp頁面,其餘web開發語言裏都有相似的動態網頁技術標準,可是無論什麼語言的動態網頁技術標準,咱們使用它時候就是讓web前端技術被服務端技術所綁架,這也就是爲何每一個招聘web前端工程師的崗位都要問你是否會java,php語言的源頭。可是隨着互聯網的大發展,對web前端的要求是愈來愈專業化,web前端自己所包含的技術難度已經不亞於任何一個服務端語言開發難度,所以咱們須要web前端更高的專業化,而不但願web前端工程師被服務端技術束縛的更多而限制了自身能力的發展,這就致使先後端分離技術的出現。

  不過先後端分離技術的第一階段倒不是從改變view層即視圖層開始的,而是從鏈接客戶端和服務端的C層即控制層開始的,控制層既要做用於客戶端又要做用於服務端,若是一個功能頁面是一個程序員從瀏覽器端一直寫到模型層,控制層也就不是什麼問題了,可是若是當咱們想按MVC的設計思想,讓界面開發人員專一於頁面開發,服務端開發人員專一於服務端開發,那麼這個時候控制層的歸屬問題就顯的很是重要了。在傳統的MVC框架裏,由於M層和C層是使用一樣的語言體系,所以咱們很天然會把M層和C層的開發工做都交由服務端開發人員完成,這個決定無可厚非,可是傳統的MVC框架裏V層和C層其本質也是同一個技術體系下的(例如java的web開發裏的jsp本質就是個servlet),所以V層和C層也是緊耦合的,所以界面開發人員開發頁面時候如何沒有C層支撐,那麼這個頁面實際上是根本跑不起來的,若是前端開發人員這時候跑去寫寫C層即控制層的代碼,這就打破了原有的橫向分工,這個時候控制層的編碼工做就會變得混亂而難以控制,看到這裏有人必定會說既然控制層是屬於服務端的,那麼前端技術人員就等等服務端的開發進度,再不行就本身寫個mock模擬下服務端的控制層,聽到這種建議,我相信無論是前端的仍是服務端的技術人員都會頭腦發麻,第一反應就是這不是自找麻煩啊,還不如一我的所有搞定算了。由此第一階段的先後端分離技術方案出現了,這個方案須要解決的問題就是如何能讓web前端技術人員和web服務端技術人員協同起來工做,合理的分工,換句話說就是按web前端和web服務端角度如何能橫向的分解web的開發工做。

       先後端分離的第一階段須要解決問題的核心就是控制層的歸屬問題,從技術角度而言就是控制層究竟是應該和視圖層解耦比較合理仍是跟模型層解耦比較合理的問題。那麼咱們這裏先回顧下MVC設計模式裏對控制層的定義,維基百科裏的定義是:

(控制器 Controller)- 負責轉發請求,對請求進行處理。

   

  不過這個解釋我認爲並不全面,以java的web開發裏的控制層設計爲例,咱們發現控制層以溝通視圖層和模型層的角度而言,控制層其實主要完成三項具體的工做,它們分別是:

  工做一:控制層起到一個路由的做用。客戶端請求到達控制層後,控制層根據請求內容將請求路由到服務端某個模型層進行處理,模型層將請求處理完畢後,會把響應結果返回給控制層,控制層在根據響應信息路由到特定的頁面。

  工做二:控制層起到一個報文信息格式轉化的做用。這裏以java的web開發爲例,瀏覽器的數據都是以http報文形式發送給服務端,而控制層就是將http報文信息解析成java的對象,固然也能夠是java的基本數據類型,而後控制層把解析好的信息傳遞給模型層進行處理。

  工做三:傳統的MVC框架裏,控制層其實深刻參入到了頁面渲染的操做。在java的web開發裏的控制層無論如何被包裝,其本質就是一個servlet,而jsp頁面本質也是個serlvet,所以咱們能夠這麼理解jsp,jsp就是以頁面開發的方式寫java,而servlet就是以java的方式寫頁面,因此咱們能夠在servlet裏以文件流的方式輸出頁面,也可讓servlet跳轉到jsp頁面。

  由上面的論述裏咱們發現,其實傳統MVC框架裏控制層和模型層的聯繫方式相對很簡單的,它們的聯繫主要是路由和報文格式的轉化上,而控制層與視圖層的聯繫除此以外還多了一個頁面渲染,而頁面渲染自己應該是屬於瀏覽器的技術範疇,是瀏覽器技術不可分割的一部分,也是我上面內容裏詬病傳統MVC框架問題所在,若是控制層承擔了頁面渲染工做,那麼控制層和視圖層的耦合度就變得很是高,要想將其解耦是十分困難,通常只有咱們打破了現有MVC框架的技術體系才能完成,相比之下,控制層與模型層的解耦就顯得容易多了。那麼控制層與模型層如何解耦呢?具體以下:

  首先咱們來解決下報文格式轉化的問題,這個技術方案很簡單就是借鑑http統一報文格式的特色,咱們爲控制層和模型層定義一套統一的報文格式,例如咱們定義控制層和模型層都以map的數據類型進行數據傳遞,這個map裏有個專門的字段用來定義被路由到的模型接口信息,有個字段專門存儲須要傳遞的數據,具體的設計方案能夠根據實際的業務須要來設計。

  接下來就是路由的問題了,在解決報文格式轉化問題的論述裏我講到要在統一報文格式裏專門定義一個字段用來存儲該數據到底路由到哪一個模型進行處理,不過這個字段並不能徹底解決路由問題,所以咱們須要模型層對控制層提供一個統一的接口,任何控制層與模型層的溝通都經過這個統一接口來完成,只不過不一樣請求報文組裝的內容不同而已,而這個接口還有個重要職責就是解析報文裏的路由信息,讓請求能被正確的路由到對應的模型接口所處理。固然這個接口的返回值最好也是一個統一的報文格式,這樣控制層解析模型層的返回數據也會便利的多了。

  由上所述,咱們發現第一階段的先後端分離工做控制層應該歸屬於web前端,這麼作更加合理,也更加容易實現,其實以後進化版的先後端分離方案,控制層也都是屬於web前端,只不過形式不一樣而已,這個我在下一篇文章裏繼續討論。

  第一階段先後端分離方案解決的核心就是讓控制層和模型層解耦,這個方案進一步演化一下,咱們能夠把控制層和視圖層獨立成一個web應用,模型層也獨立成一個web應用,兩個web應用之間經過遠程調用方式進行溝通,這個方案我在之前文章裏寫過,這篇文章的名字叫作《我設計的網站的分佈式架構》。

  這個進化版的方案增長了系統開發的難度,由於咱們須要增長網絡通訊的編程以及遠程調用的實現,更麻煩的是咱們還須要進行復雜的多線程編程,既然增長了開發的難度爲何我還要這麼作呢?首先咱們經過應用分層,能夠動態的調節web前端和web服務端的負載壓力,還能夠在模型層以前提供一道安全屏障,不過被服務端綁架的web前端在提高整個web應用負載能力這塊仍是頗有限的,其實這種作法的最大好處就是利於SOA框架的設計,也就是說這種架構咱們能夠爲服務端的SOA化提供有力的保障,由於控制層和模型層的解耦,可讓模型層真正作到專一於業務,而不會再發生那種把業務邏輯寫到控制層的問題了從而下降代碼的健壯性。

  好了,今天就寫到這裏,最好祝你們新年快樂,晚安了。

相關文章
相關標籤/搜索