架構設計:前後端分離之Web前端架構設計

 在前面的文章裡我談到了前後端分離的一些看法,這個看法是從巨集觀的角度來思考的,沒有具體的落地實現,今天我將延續上篇文章的主題,從純前端的架構設計角度談談前後端分離的一種具體實現方案,該方案和我原來設想有了很大的變化,但是核心思想沒變,就是控制層是屬於Web前端的。

  在以前文章裡我說道前後端分離的核心在於把mvc的控制層歸為前端的一部分,原方案的構想在實際的生產開發裡很難做到,我覺得核心還是控制層和檢視層的技術異構性,這樣後果使得系統改造牽涉面太大,導致在專案團隊裡,溝通、協調以及管理成本相對較高,隨著前端技術的發展,前端開發的工程量是越來越大,難度也是越來越高,因此前端工程的專案化,工程化和獨立性越來越被人重視了,所以出現了大量的javascript MVC的富應用。如果javascript也能做到MVC模式,那麼前端框架就可以拋棄異構語言的控制層,做到真正的獨立。

  要把傳統的MVC的C層從前端剝離掉,我們首先要理解下MVC的C層即控制層到底做了什麼樣的事情,控制層的作用是模型層和檢視層溝通的紐帶,模型層進一步具體點就是資料層,檢視層具體點就是資料展示給使用者的方式,下面我們看看java的Web應用裡,控制層和檢視層是如何耦合的呢?做過java的web開發的人第一個反應就是頁面裡回嵌入大量java程式碼或者使用jsp的標籤或者使用velocity,freemark這樣的模板語言,這些東西大家很自然的把它們歸為服務端的東西,但是它們卻出現在了檢視層,所以檢視層和控制層沒法解耦,其實除了這個還有一個大家很熟悉但又很少把它歸為是檢視層和控制層的耦合因素,這個因素就是頁面的跳轉,用ajax的角度描述這個因素就是頁面的同步提交,這兩個因素也就是構成了控制層的核心應用(是應用資料和頁面展示的橋樑)。

  要將前端獨立起來,控制層歸為前端是不可改變的定律,如果服務端的人太傲慢無禮,不肯放掉控制層,那麼前端就必須自己來做控制層,那麼前端做控制層的難點就是解決前端技術如何做到解決服務端資料展示和有時無法避免的同步提交問題,解決服務端資料展示問題就是要在javascript語言裡找到替換java程式碼、jsp標籤以及velcity這樣的模板語言的技術,很幸運在javascript的確擁有這樣的技術,這就是微軟公司貢獻的jQuery的模板語言jquery-tmpl,它的訪問地址是:

  https://github.com/BorisMoore/jquery-tmpl

  百度搜索的地址:

  http://www.baidu.com/s?wd=jquery%20tmpl&rsv_spt=1&issp=1&rsv_bp=0&ie=utf-8&tn=baiduhome_pg&rsv_sug3=8&rsv_sug4=1397&rsv_sug1=8&oq=jquery%20tm&rsv_sug2=0&f=3&rsp=0&inputT=13948

  有了javascript的模板技術,我們就可以不用在頁面再寫入服務端的任何東西,這樣就達到異構語言的控制層和前端的分離,從而摒棄服務端的控制層。而模板語言需要的資料就可以通過ajax請求傳送到頁面,ajax接收到資料後傳輸到javascript的模板語言裡最終就可以達到服務端資料在頁面上的展示,使用這種方式展示資料好處不僅僅侷限於控制層和檢視層的解耦,同時還會提升頁面的響應效率,因為通過這種方式,資料和服務端的交換不再需要檢視展示要素即服務端直接傳送個頁面,或者是頁面的片段,然後操作dom使得這些檢視性的東西展示到頁面上的行為,而現在服務端只需要傳輸需要傳輸的資料就行,這樣一個http請求的資料傳輸量會大大減少,減少http請求的資料大小是提升網站載入效率的重要指標之一,同時如果傳輸只需要最必要的資料,那麼服務端和前端的互動就可以做到統一的報文格式,使用統一的報文規範,這樣會對專案管理,系統運維和維護帶來質的飛越。

  讓控制層徹底歸為web前端的第二步就是要讓web應用的同步提交操作徹底死翹翹,而傳統的同步提交只要承擔整個web應用的入口的功能即可。談到這裡我想如果對web前端開發有過經驗的人看到上面這句話就很容易聯想到現在很火的單頁面開發,沒錯我的確在講單頁面開發,其實javascript MVC的最高境界就是單頁面模式。

  雖然時下的web應用是ajax的天下,但是如果我們想徹底的拋棄同步提交請求的想法真的應用到實踐中,開發人員會發現它常常會變成一個吃力不討好的事情,為什麼說它是一件吃力不討好的事情,我想主要體現在兩個方面:

  第一方面:ajax請求往往是作為純資料的傳輸,那麼頁面效果的顯示就需要開發人員自己操作DOM,使用各種javascript開發技巧,這就大大增加頁面開發難度和複雜度,對於一個要投入市場的web應用,其成本和風險是可想而知的。

  另一方面:同步提交頁面會讓使用者享受一種很頂級的使用者體驗,這就是瀏覽器的前進和後退體驗,如果讓ajax做前進和後退,特別是使用者和網站互動量很大的網站,這個操作可能會成為一件不可能完成的任務。

  這裡我首先講如何解決前進和後退的問題,在瀏覽器的請求url地址有一個很重要的特性就是hash屬性,例如我們寫頁面時候常常會寫到這樣的語句:

<a href=”#” onclick=”ftn()” id=”btn”>btn</a>

  當用戶點選這個連結時候,會促發click事件,可能很多人沒有留心到此時網頁請求的url後面會新增一個#號,例如:www.cnblogs.com/#,如果我們把這個連結改下,如下:

<a href=”#sharpxiajun” onclick=”ftn()” id=”btn”>btn</a>

  再點選這個連結,我們會發現連結變成了www.cnblogs.com/#sharpxiajun,前面的#sharpxiajun就是url的hash,url的hash是不會發送給服務端的,不過在瀏覽器裡有專門的事件可以監聽到它,這個事件就是hashchange事件,它是一個window的事件,瀏覽器的前進與後退支援url的hash改變,同時window可以監聽到該事件,因此我們可以通過改變url的hash再加上ajax請求就可以模擬頁面的同步提交了,同時該請求是可以使用瀏覽器的前進和後退操作。

  使用url的hash屬性模擬同步的url,那麼我們就可以將頁面的url改成一個帶hash的url地址,例如傳統網站的註冊頁面地址應該是:www.cnblogs.com/register.html,現在可以改為www.cnblogs.com/#!/register,如果註冊頁面的上游頁面是www.cnblogs.com/,那麼我們在註冊頁面點選回退按鈕時候頁面就會跳轉到www.cnblogs.com/

  如果我們web前端擁有的以上我所講述的技術,那麼一個web應用的控制層可以完全平移到了web前端,而web前端可以做到真正的專案獨立,到時web前端只要和服務端建立合適的報文規範,使用時下流行的json資料格式,就可以完成Web應用的開發,這樣的web應用就做到前後端的真正分離。

  使用我講到的技術開發網站,瀏覽器的通訊都將是ajax,這個ajax按應用場景可以分為兩種型別:一種型別是模擬同步提交的ajax,這個請求時獲取檢視,也就是頁面,這個功能可以當做一個路由功能,這是控制層控制檢視層的操作,另一個ajax就是獲取資料,ajax獲取到資料後,通過javascript模板技術進行轉化,最後控制層將轉化的資料和檢視層結合到一起,最終將完整的頁面呈現給網站的使用者。

  Javascript做控制層其實是通過url的hash完成的,核心是使用window的hashchange事件,這裡就有一個web前端開發最頭疼的問題,是不是所有瀏覽器都支援hashchange事件了?答案是:新瀏覽器都支援,最可惡的ie,在8以上包括8都支援,那麼我們想讓所有瀏覽器都可以使用hashchange怎麼辦來了?jquery有個外掛可以讓低版本的瀏覽器支援hashchange事件,有興趣的人可以百度一下,不過如果是在移動裝置上開發web應用時完全不用擔心相容問題。

  前面我用到一個帶hash的url:www.cnblogs.com/#!/register,#!/xxx是我推薦給大夥的書寫形式,理由是:我們做一個網站都需要給搜尋引擎示好,但是搜尋引擎的網路爬蟲都是抓取靜態頁面,對於ajax請求的靜態頁面往往無能為力,因此我們要讓搜尋引擎的網路爬蟲能找到我們的頁面所以在#後面加上!/,很多高階的搜尋引擎會抓取到我們網頁上的內容,這裡主要是指google,百度的是不是有類似的能力,俺就不清楚,這個就得問問度娘了。

  我之前在我的部落格裡給大夥分享了我自己寫的一個javascript框架,當時我使用一個檔案,一個庫來完成我的框架,這樣的框架其實只能算是把一個Web開發裡能通用的東西做了一個抽取和彙總,換種說法就是以前的框架是一個工具類大集合,但是到了我今天講的web前端的javascript框架,這樣的工具類是不能滿足我們的需求,原因是控制層被移到了web前端,這樣web應用的資料模型及模型層和控制層對檢視層的路由功能同時也遷移到了web前端,那麼某一個頁面對應的資料模型以及對應的檢視頁面,我們應該讓它和別的資料模型和對應頁面有一個明顯的界線,具體實現裡就是一個檢視及一個頁面對應的javascript程式碼應該要模組化,所以我們最好一個頁面對應一個javascript檔案,這樣我們就要對javascript程式碼進行模組化管理,要引入requieJS或者國產的seajs工具,具體的使用有興趣的童鞋可以百度或者google一下。

  如果我們不會用requieJS和seajs怎麼辦了?大型網站的javascript程式碼和css程式碼在生產上都會盡量的合併成少量的檔案,因此我這裡建議大家要用面向物件的方式組織自己的javascript程式碼,這裡我推薦一個借鑑與jQuery架構類似的javascript框架模板:

(function($,params){
function MyObj = {
return this._init.apply(this,arguments);
}
myObj.fn = myobj.prototype;
myObj.fn = function(){
return {
_init:function(){// 初始化方法
this.setting = arguments;
return this;
},
_bindEvt:function(){// 事件繫結
程式碼…
return this;
},
_pageLoad:function(){
_bindEvt();
程式碼…
return this;
}
}
};
// 給類新增屬性或方法,相當於靜態變數
myObj.extend = function(obj){
var extended = obj. extended;
for (var i in obj){
myObj.fn[i] = obj[i];
}
if (extended) extend(myObj);
};
myObj.load = function(param){
return new myObj(params)._pageLoad();
}
return myObj;
})(jQuery,params,undefined)

  該框架的load方法相當於java的main函式,這裡我們使用javascript物件的技術構建物件,那麼該物件對外就很容易擴充套件,每個原型prototype方法都會返回this指標這樣就可以達到jQuery裡方法連綴的寫法。

  其實這樣的結構最後也能應用到requieJS和seajs裡面,這樣寫的javascript程式碼的結構性和層次性更好,擴充套件性更強。

  好了文章寫完了,本篇文章一氣呵成,難免有遺漏錯誤地方,到時還請認真的童鞋及時指出。

混搭.NET技術

新聞 .NET技術+25臺伺服器怎樣支撐世界第54大網站 再度燃起人們對.NET的技術熱情。這篇新聞中透露了StackExchange 在技術方面的混搭,這也是我所崇尚的。因此我也在社群裡極力推廣Mono平臺,這篇短文就想和大家一起討論一下混搭.NET技術。

混搭(Mashup)架構是一種新型的整合各種技術的應用開發架構。傳統上,Mashup源於流行音樂,是一種音樂型別,也被稱為bastard pop,指的是藝術家組合或者混合兩首不同的歌曲(通常屬於不同的流派)的音樂和歌詞來創作新的歌曲。它擁有三個特徵:天生的創新性,人們的經驗性和結果的和諧性。 
特徵一:天生的創新性。從起源上看,Mashup是一種內容上的創新組合。這裡重點是創新,雖然組合的元素通常都源自於本來無關但非常常見的東西,但這和任何創新活動類似,一旦組合便會產生一種具有新意的新生事物。 
特徵二:人們的經驗性。這些組合都是人工進行合成的,而不是通過計算演算法來合成的,人們的經驗和思維在Mashup過程中起到了決定性作用。 
特徵三:結果的和諧性。無獨有偶,在現實社會中Mashup風潮也影響著服裝時尚界,設計師們把街頭朋克元素引入到傳統的英格蘭服飾,用運動T恤混搭具有少女風情的篷篷裙,產生了意想不到的匹配效果。時尚界也稱Mix & Match風格,從字面上理解,Mix是混合,Match是匹配,合起來翻譯成混搭。指將不同風格,不同材質,不同身價的東西按照個人口味拼湊在一起,從而混合搭配出完全個人化的風格。Mix就是混合兩個或多個元素,來展現新的使用者體驗。Match是指一種和諧相配的有機組合,否則就是“瞎搭”了。這就是特徵三,混搭結果必須和諧匹配,具有這種既混且搭的東西,現實生活中除了音樂和服裝,還有中國火鍋,多元文化,多元的收藏,裝飾和建築風格等等,人們的情緒可以說也是一種混搭的表現。

對IT技術來說,就如同創造新音樂,新服裝那樣,它能讓開發人員創造針對特定的業務需求的業務混搭IT技術。下面我們來看下StackExchange 在技術方面的混搭:

1、混搭Windows和Linux

Stack Overflow 把系統部署在Windows 平臺上,同時使用Linux系統上,什麼好用用什麼,不要做無必要的系統之爭,比如 C# 在 Windows 機器上執行最好,我們使用 IIS;Redis 在*nix 機器上可以得到充分發揮,使用*nix。還有 Windows上也有IIS ARR,但是他沒有Linux上的Haproxy好,所以它使用Haproxy,同樣的還有Windows上有nlb,Linux上有LVS,LVS 比NLB 好太多了,所以不要侷限於所使用的系統,完全可以混搭使用Windows和Linux。

2、混搭物理伺服器和虛擬機器

硬體永遠比開發者和有效率的程式碼便宜。基於木桶效應,速度肯定受限於某個短板,現有的雲服務基本上都存在容量和效能限制。StackExchange 混搭使用了物理伺服器和虛擬機器,物理伺服器可以將發揮縱向擴充套件的威力,資料庫伺服器使用SSD 磁碟,365GB記憶體 ,這樣高配置的伺服器現在雲平臺上基本沒有,同時在一些低負載的場景使用虛擬機器,例如VM 用於部署、域控制器、監控、運維資料庫等場合。

3、混搭.NET開源社群技術

Stack Overflow 主要使用微軟的.NET技術,混搭.NET開源社群的技術。 Stack Overflow本身就是.NET開源社群的一個參與者,他運用了redis作為其快取層,目前最流行的Redis的.NET 驅動就是ServiceStack.redis,它是Stack Exchange的一位開發者Demis Bellot 所開發的開源的、支援.NET與Mono平臺的REST Web Services框架ServiceStack 的一部分。微型的 ORM ——Dapper也是 Stack Overflow 開源的,還有Stack Overflow的開源監控解決方案Opserver,也是 Stack Exchange釋出。它基於.NET框架構建,這在監控工具領域有些與眾不同。

4、混搭其他技術

使用 http://logstash.net/做日誌管理,SSD 改變了搜尋的使用方式。因為鎖的問題,Luncene.net 並不能支撐 SO 的併發負載,因此他們轉向了 ElasticSearch。

在眾多的技術方案中,不同的技術方案都有它的優點,不過從單一的方式來說,也會有缺點,但兩種技術方案的結合混搭,就可以解決這些問題,最大程度上發揮各自優點,彌補不同技術方案的缺點。不過只有象StackExchange 具備豐富的技術能力的專業團隊,才能很好的完成混搭,讓後期的使用安枕無憂。

任何一個技術方案,管理都會有風險,混搭當然也會有。因此,在進行混搭創新之前,首先要對混搭的技術有一個準確的評估,比如你的技術方案與要混搭創新的技術之間有沒有優勢互補,微軟在2011年以前經常是複製社群的技術,一個微軟技術的使用者侷限於微軟的技術,這就好比是近親繁殖,微軟現在已經改變策略,直接整合社群的技術,這也是一種混搭創新,特別是使用微軟技術的同仁們也要學會混搭;第二點,在進行混搭創新的變革之前,要和整個公司團隊有充分的溝通,讓你的團隊很清楚地知道為什麼要進行這樣的混搭創新,,大多數人都不大喜歡被改變,所以領導者決心要變革、要創新就必須說服成員,告訴他們不改變會怎樣。

2014年的.NET技術已經進入一個新的高度,.NET vNext 有一個專門為雲端環境優化過的模式,該模式允許你在部署程式的時候連同他們所用到的.NET Framework的相關庫一同部署。由於.NET的執行時和框架中的庫部署在了程式基礎(app-basis)上,所以在同一臺機器上,每一個程式可以執行不同版本的.NET vNext,並且可以單獨升級,互不影響。這些庫已經被顯著的優化、精簡以便減少框架佔用的空間,並且將會使用NuGet來發布。.NET開發團隊以跨平臺的思想來開發這個模式,在開發過程中和Xamarin積極合作,以確保經過雲端優化過的.NET程式可以執行在裝有 Mono 執行時的Mac和Linux上。一次將非Windows主機作為一等公民對待。微軟將Mono和Linux完全整合到他們的構建環境和測試矩陣中,並積極地與社群共同努力將Mono變成一個託管ASP.NET的頂級平臺,Xamarin最近也在行動,劍橋大學的開源顧問全職加入Xamarin 公司,他的工作是確保Mono 成為Linux上的一等公民。訊息來自他的部落格 http://t.cn/RPLN4Hj。.NET和ASP.NET的巨大生產力可以提供給那些使用混合開發環境的團隊。