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

先後端分離的主題雖然講完了,可是先後端分離的內容並無結束,本篇將繼續先後端分離的問題,只不過此次先後端分離的講述將會圍繞着本系列的主題網站靜態化進行。在講本篇主題以前,我須要糾正一下先後端分離主題講述中會讓朋友們產生誤導的地方,這種誤導就是對時下流行的一些先後端分離方案(沒有使用nodejs的先後端分離方案)的評價問題,其實本人任然以爲無論什麼樣的先後端分離方案只要成功被實施,而且產生了良好的效果,那麼它就是一個成功的先後端分離方案,前面我以一種批判的角度講述這些先後端分離方案,並非想在否認它們,而是出於一種雞蛋裏挑骨頭的較真態度想從新審視這些方案,但願這種審視能讓咱們的設計方案變得更加優秀,同時本身也在這個較勁的過程裏獲得自身技術能力的提高。其實那些被我批判的技術方案也許在某些特定場景下它就會變的更加優秀,我推崇的技術方案在某些場景下可能就變的蒼白而無力,這種狀況頗有可能發生,不說別的,我之因此批評前端MVC,其私心就是由於它不符合網站靜態化的處理,若是把前端MVC內容放置在網站靜態化的主題下談論,被批的命運那是必然的。 javascript

  網站靜態化技術相對於先後端分離技術的關注度要低的多,若是業界的一些公司由於看了本人的文章能對網站靜態化技術有一種新的認識,從而考慮在本身網站上使用網站靜態化技術,同時也想實現先後端分離技術,那麼新的問題出現了,這兩種技術同時使用會發生矛盾嗎?若是有矛盾,咱們到底將如何解決這些矛盾?解決這些矛盾的時候咱們是否是能夠作好二者的兼顧,而不會發生其中一方妥協於另外一方,最終致使其中一方沒有充分的發揮本身的能力。要解答上面的一系列問題,我首先要探求的就是網站靜態化技術和先後端分離方案裏那些方面會產生矛盾。 html

  從我前面對網站靜態化技術的闡述,咱們知道網站靜態化的技術最佳做用位置應該是服務端而非是瀏覽器端,之因此會這樣是由於網站靜態化技術的技術基礎是動靜分離和緩存,這兩個方面若是落到瀏覽器端會碰到不少難以解決的問題,那麼咱們要分析下這些難以解決的問題,具體以下: 前端

  瀏覽器之緩存問題:瀏覽器也有緩存,不過瀏覽器端的緩存那就不是指內存裏的緩存,而是持久化的緩存,實際上瀏覽器端的緩存很是不可靠,會被不少非技術的因素所限制,例如咱們手動刪除緩存或者使用無痕模式上網,那麼這些持久化的緩存就會失效,用戶再度訪問網站時候都將是第一次訪問這個網站,這就使得不少優秀的緩存策略方案在瀏覽器端實施效果大打折扣。 java

  瀏覽器之動靜分離問題:網站靜態化技術裏一個重要的手段就是如何設計動靜分離策略,純粹的靜態內容這個沒啥好說的,可是動態的內容在必定的條件(例如:時間,一些業務屬性例如商戶屬性)下是能夠轉化爲靜態內容,這些內容若是能被有效緩存,對網站性能提高是不可估量的,並且這種動靜轉化的策略也能夠減小業務服務器上處理沒必要要的請求,從而減輕業務服務器的壓力,達到提高後臺核心業務服務端的負載壓力。可是若是咱們使用前端MVC框架,一股腦子把不少服務端功能往前端遷移,那麼這種動靜處理手段就很難作,並且不少場景基本上是沒法應用了。 node

  所以我認爲先後端分離方案使用nodejs價值更高,由於使用nodejs咱們就能夠根據網站靜態化技術將須要保留在服務端的功能能夠繼續保留在服務端,這樣就能達到兩者兼顧的目的。可是若是咱們認爲把nodejs引入後,nodejs的目的就是用來作網站總體MVC架構下的C層即控制層,這個思路到底合理不合理呢?這個問題仍是很值得玩味的,所以咱們須要分析下網站總體MVC架構下的C層即控制層的做用。 web

  在前面文章裏我曾總結過C層即控制層在MVC框架裏的做用,這個做用分別是:路由、報文格式轉化以及頁面渲染,可是這個做用的總結我是有個前提條件的,那就是以C層即控制層做爲先後端溝通介質的前提下。若是先後端分離方案引入後把控制層歸爲前端的組成部分,那麼控制層跟前端的結合問題都是人民內部的矛盾,都是比較好解決,可是控制層就僅僅是用來鏈接先後端一個做用嗎?對於網站架構裏的控制層,有一個不可避免的功能那就是做爲後端服務端的安全入口的做用,也就是說控制層是作請求安全檢查和安全監控的地方,並且不少安全校驗還會和業務相關,例如檢查報文是否被篡改啊,防釣魚的功能,若是這些功能被前端來承擔,首先不談前端技術人員會不會作這些,可是至少一點問題是會發生的,前端工程師在關心頁面開始同時還要寫服務端的業務邏輯了,無論怎麼說,這些功能遷移到前端總不是太合適。當網站演變爲超大型網站後,大型網站每每是不少小中型網站項目的集合體,爲了減小網站總體的異構性,咱們經常把不一樣的模塊網站的入口整合在一個大型控制層項目下面,這個大型控制層項目通常稱爲網關項目,它的做用和網絡裏的網關很是類似。除此以外,還有些網站的控制層很是特別,例如一些作第三方支付的網站,那麼這樣網站項目自己就是個大網關,並且這個網關很特別,它後臺的服務就是其餘銀行的系統,它的路由工做就會變得異常複雜,例如:根據用戶使用銀行的不一樣,控制層要組裝不一樣的報文信息,而這些功能都是屬於控制層,這樣的場景無疑大幅度提高了控制層再和模型層對接的技術難度,而增長的難度問題又和模型層耦合度很高,因而可知,web應用總體的MVC的控制層比咱們想象中要複雜的多。 後端

  回到用nodejs替代控制層這個主題,咱們來看看實際的場景吧,假如咱們的網站控制層相對比較簡單,好了,這時候咱們跟領導或老闆說"如今很流行先後端分離,咱們項目也使用下先後端分離技術",領導或老闆一聽可能會爲之一振,那麼就會問你"那麼該怎麼作了",你這時對他說"首先把控制層用nodejs重寫下",領導或老闆聽到這個回答他會贊成你這麼幹嗎?一個不會給網站增長任何新功能,同時不能很直接有效的提高網站的性能,並且執行它還會有很大風險的方案,頭兒們會贊成嗎?好了,假如你終於找到合理理由說服頭兒們,那麼若是咱們的網站規模已經很大,控制層已經演變成了網關項目,控制層自己已經巨複雜了,你敢用nodejs重寫一遍網關項目嗎?因此說吧nodejs直接當作控制層,其實實踐起來困難重重,並且nodejs徹底承擔控制層,它的性能,它可否很好的運用於集羣開發這都是很難把控的問題。分析到這裏,咱們彷佛又進入了死衚衕了,那如何來破這個局呢? 瀏覽器

  上面的問題只是反映出整個網站MVC裏的控制層其實還有部分功能是和服務端的模型層緊耦合的,所以要解決這個問題就是把傳統的控制層再細分一下,屬於前端的部分劃分給web前端做爲web前端的控制層,屬於服務端的部分任然留給服務端,這麼拆分後,當咱們引入了以nodejs爲基礎的先後端分離方案,服務端的控制層改造無非就是去掉頁面路由,頁面渲染,再修改下返回數據格式便可,由於不用修改服務端的業務代碼,其代價是很低的,頭兒們也很容易接受這樣的方案,並支持咱們大膽去嘗試新技術。 緩存

  服務端網站靜態化技術SSI和ESI,主要是根據動靜分離策略把網頁不會常常變化的模板進行緩存,而後在靜態資源服務器位置整合動靜資源,若是咱們使用nodejs只是簡單替換原來的控制層,那麼這些策略其實仍是有問題的,那麼怎樣作可讓nodejs兼容SSI和ESI了?這裏我列舉個實際的案例,nodejs有一個模板語言叫作jade,nodejs裏還有個技術叫作handlebarsjs,其中handlebarsjs和struts的標籤相似,它能夠處理一些簡單的業務邏輯,咱們開發時候使用jade編寫頁面的模板,使用handlebarsjs讓動態數據和模板進行整合,項目發佈時候,使用像grunt這樣的項目管理工具編譯項目,jade文件變成html文件,而handlebarsjs則會轉化爲javascript代碼,這樣咱們就能夠把生成的html文件在服務端進行有效緩存,而handlebars生成的javascript文件負責整合動靜數據,這樣nodejs就能夠達到兼容SSI和ESI的做用了。 安全

  不過引入nodejs會讓網站處理請求的過程裏增長一個環節,這樣可能會致使部分性能的損失,可是我上面的實例卻能有另外的方式規避這個問題,由於nodejs的代碼是用javascript語言編寫的,那麼這個代碼是能夠運行在瀏覽器上的,那麼這就會產生了一個處理手法,那就是咱們在生產部署時候其實不須要部署nodejs的,咱們把靜態模板就緩存在服務端或者推送到CDN上,而後handlebarsjs生成的js代碼就讓它傳送到瀏覽器端,由於這個js代碼生成後基本不會變化,瀏覽器能夠緩存它,固然CDN或靜態資源服務器也能夠緩存它,其實它在瀏覽器運行時候變化無非就是獲取一次服務端數據而已。這麼一來,生產上的web前端又轉變成了前端MVC的形式,還把動靜整合的事情交由了瀏覽器來完成,這不只是兼顧的網站靜態化要求,還讓動靜整合推到了更加靠前的瀏覽器端,這不是達到了一個共贏的效果了嘛。

  好了,本篇就寫到這裏,最後祝你們晚安,生活愉快

相關文章
相關標籤/搜索