Web開發技術的演變

wildfly發表於2013-08-08

  受到好文《Web開發的發展史》激發的靈感,寫下我對web開發技術的認識。

  1. 靜態頁面時代

  大學時候,上機還得換卡穿拖鞋,Novell的網路是很神奇的,然而更神奇的是通訊原理老師半神祕的講他上Internet,“Cernet(教育網)有條64K的出口,半年前還很快,現在已經比較卡了”。就這樣,我們用Netscape指向Yahoo。那是一個HTML加圖片的世界,充斥著各種花哨閃耀的字型和鞠躬的小人,藍色連線點選後會奇幻的變色。

  我們開始用不熟練的HTML和簡陋的設計來設計網頁,並且知道這邊有個瀏覽器,那邊有個叫WebServer的東西,但管理Sun工作站的機房老師總是盯的很緊,不會讓你動系統半分。聽說有個叫Linux的神奇東西,好吧我想嘗試,可是我只有一臺攢的電腦,以及若干張5寸3寸的軟盤。我至今感謝一位師兄,他幫我下載並切分了一個版本的Mandrake,就這樣室友看到非常奇怪的一幕,我奔波在機房宿舍之間,仔細計算容量來拷貝,就這樣在假期裡我第一次搭建了Apache。

  2. CGI時代

  很快頁面上流行一個叫做計數器的東西,免費的收費的建站網站都把它當作賣點,“立體超炫變色時尚計數器”,很快我們看到幾乎每個頁面都有了一個點選量在88888的酷裝置,只是無論怎麼點都不會變化。而校園裡張貼著令人眼紅的廣告,“徵人寫CGI程式,一支500元!“。

  慢慢的,知道了CGI是利用程式間輸入輸出通訊,和WebServer進行通訊,從而可以寫程式來控制頁面輸出的內容。但在當時會給硬碟分割槽就在中關村被看成電腦高手的年代,實在是會者寥寥。即便到了今天,我依然對Perl敬而遠之。一些前輩用C寫出更高階的CGI應用,比如WebMail,挖到第一桶金,成為今天網際網路的先驅。

  3. PHP露出鋒芒

  說實話,我認為PHP是最受益於網際網路浪潮的語言,在合適的時間和好夥伴Mysql一起出現。利用Apache的模組mod-php,將php作為web伺服器的一部分執行,效率和維護性都達到很好的提升。指令碼語言成為網際網路前端開發主力一直到今天。PHP和大哥Perl,以及兄弟Python,Ruby一起盤據在程式語言排行榜5-10名位置。

  同樣的Mysql也是時代的嬌子,它快速靈活易用成為網站資料庫的首選,但很長時間裡,Mysql被其他資料庫詬病,別說Oracle等高富帥,即便是同為開源的Postgres社群裡,也會有這樣的聲音,“不支援事務也叫資料庫?”。沒關係,開源社群很快為其加入各種引擎,如今Mysql絕對是裝機總量第一的資料庫。

  4. J2EE

  Java時代來臨,一杯咖啡,一個可跳動的小精靈牽動了所有的大型軟體公司。沒錯是所有,包括微軟,Sun公司一時星光無限,所有的開發人員都在談Java。人們對其桌面表現失望進而質疑時,J2EE及時出現了,Servlet+JSP快速成為Web開發的好用技術。能夠跨平臺,獨立解包使用的Web伺服器,掛接任意資料庫的JDBC介面,一時世界變得很美好。

  微軟的ASP也出現了,一開始也是指令碼解釋,和PHP等技術類似。很快微軟的C#和dotNET戰略出臺,ASP也升級為ASP.Net,從此dotNET和J2EE是競爭者,更是一對站在相同站壕的朋友,互相學習和抄襲對方的技術和設計,直到今天。

  5. Web層框架百花齊放

  Servlet是一個優異的Web技術規範,但面對叢多的開發需求,還是不能很好的覆蓋。Struts框架很快成為主流,今天我們依然看到很多.do字尾的頁面。Struts主要做了三件事,一是對請求Url進行很好的梳理,通過Command模式把請求指配到Action物件上,並可以用同期出現的Ioc框架進行注入。二是梳理出若干有用好用的Intecepter,並可以自由組合構成自己的Stack。三是對頁面流轉流程通過xml的方式可以靈活定義。

  同期,數以百計的各種框架出現了,多數都是針對Servlet的空白點,在幾個方面進行程式碼或者配置的約定,可謂百花齊放,百家爭鳴,我想Java社群能到今天依然繁榮,這種海納百川,開放的態度是根本原因。如今很多框架已經走過生命期,但還有很多活躍的,其中Webwork即Struts2,和SpringMVC是模板技術類別最出色的。GWT,Wicket等在頁面元件類表現不錯,還有脫離Servlet束縛Play等框架。

  6. WithoutEJB

  J2EE裡,除了Servlet外另一個重量級的規範就是EJB。EJB設計的來源是Corba技術,分散式物件技術在EJB規範中有完整的體現。Rod在著作中對EJB規範粗重龐大難用提出各種質疑,尤其是針對其強制分佈的要求。我的觀念是分散式支援沒有錯,現在EJB規範中對於Local和Remote的劃分定義是正確的。開發人員應該一開始就需要了解介面粒度的劃分,本地和遠端介面是不同的。對於一般的小型應用,Servlet和EJB容器都在一個虛擬機器中,本地介面是合理的,但對於大型企業應用和網際網路級別應用,勢必需要服務的遠端劃分和呼叫。所以早期的EJB,可以說一方面設計不完備,另一方面又過度設計。但EJB自從3以後完全脫胎換骨,成為設計良好的規範。

  Spring作為開發框架,把Ioc和AOP能力發揮的淋漓盡致,在各個層次很好融合其他技術和專案庫,一直是Java Web開發的主流。不過面對CDI等JavaEE規範,在注入,生命期管理,物件解耦等優勢不在。我預計今後Spring, JavaEE和Osgi會在主流Java開發框架方向競爭,也會相互借鑑和融合。

  7. Ajax

  Javascript是瀏覽器正統的指令碼語言,但在那個機器效能不佳的年代,一段Js程式碼造成滑鼠沒有響應的情況比比皆是。Js的給人影響就是頁面上飄來飄去“點選我”對話方塊,頁面上走馬燈效果的變色通告,或者是幾十層模態對話方塊的惡意頁面,很多網咖的機器預設Js是禁用的。在很長的一段時間裡,Java web開發一個潛規則就是少手寫Js檔案,這樣可以很好的支援多種瀏覽器和提高效率。

  谷歌火了,Ajax也成為火爆的前端技術,我們在使用gmail,google map等產品時,有了另一種體驗,點選連結或按鈕後,即便網路不算流暢,頁面不再全白重新重新整理,而是內容漸漸的出現。其原理就是利用Js指令碼到後臺伺服器獲取資料,在瀏覽器前端對資料進行解析和渲染,在這個過程中,大多數頁面並不需要進行改變,只是更新頁面中一部分即可。谷歌公司大力支援Firefox使其重生,並和蘋果一起發展webkit專案,各自發展了chrome和safari瀏覽器,伴隨者頁面渲染能力大力提升同時,Js指令碼的解析能力也突飛猛進。我個人認為Ajax這個技術看似簡單,但卻是新一代Web,所謂Web2.0的基石性質技術,為網際網路泡沫後網際網路的復興和今日騰飛起到了重要作用。

  8. Ruby and Rails

  快速成長的網際網路需要快速的web開發能力,Rails框架出現了,同時火爆的還有Ruby語言,它的出現滿足了當時開發者的需要,快速開發,玩cool的東西,有完備的後端模型支援。讓我們仔細分析一下Rails中MVC就能發現,Model中對實體物件的關係定義,和JavaEE的JPA很多概念一致,但利用Ruby語言的元能力,可以直接對實體物件進行功能擴充套件,而其時Java社群還在為貧血,充血物件爭論不休。Control,View等層次也能和Java的一些框架概念一致,不過有些設計構思更巧妙,而且Rails的基因就是滿足網際網路開發需要,和JavaEE企業級應用有所不同。

  很快的,各種語言紛紛出現模仿Rails的專案,Java的Grails, SpringROO,JBossForge,Python的Django,PHP的Symfony等等。毫無例外的,能有影響力的都是開源的,有良好社群能力建設的專案。

  9. JSF和CDI

  讓我們回到企業應用開發,大家有沒有想過所謂企業應用和網際網路應用之間最大的差別是什麼?我認為是使用者數量級別的差異,導致前端設計方式,軟體體系,後臺資料庫,快取技術應用,有不同的設計理念和方式。用更技術化來說,就是會話和事務。企業應用是有強會話和事務需求的,而這兩個技術詞語也會一併關聯存在。很簡單,在一個事務中會經過多次會話過程,直到這個事務全部做完。和我們日常辦事是一樣的,填單子,和辦事人員溝通,修改單據,蓋章,各種口舌,最終感慨,辦事真難。

  從軟體層面考慮,一個企業應用軟體可能使用者數並不太多,就企業中百十號人,但前後臺的互動是長時間,多次會話互動的。JSF技術其實是借鑑了微軟ASP.net,它們繼承了傳統IDE快速開發的思路,希望通過拖拽連線可以快速開發一個應用。頁面上的元件,對應後臺伺服器的業務元件,在得到伺服器請求之後,元件需要做一系列動作來完成解析,校驗,模型重建,業務方法呼叫,頁面渲染等步驟,這些必然有個較長的過程。複雜性,效率,和其他技術的融合,JSF技術從誕生起就被質疑不斷,而且面對每個明星技術,都有些格格不入,比如Ajax出現了,而JSF要求的Post方式還需要重刷頁面。但JSF一直在改進,越來越科學完善。如今,配合CDI,JSF是企業應用開發的首選技術之一,大家可以研究一下Oracle的應用產品和ADF開發框架。

  CDI是Seam框架的技術精華形成的JavaEE規範,在JavaEE7裡面已經成為最重要的規範之一。和Hibernate最終形成JPA一樣,CDI也是GavinKing構思,開發推動的。仔細分析就會發現,CDI幾乎彌補了JavaEE在現代開發需求中,物件方面定義的絕大多數不足,比如和DI規範定義了注入,生命期管理和會話範圍定義,完善了EJB對於普通POJO對於事務,非同步通知機制的定義,還有註解的堆疊定義,裝飾模式等等。有時候我就在想,假如JavaEE是GK從頭打造,我們開發人員會少走很多彎路,因為他對企業應用的理解和用Java構建框架和定義規範,都是貼近一線開發人員需求。唯一遺憾的就是CDI還沒有推動完成,他轉移興趣玩起語言了。關於JSF和CDI,我建議做相關產品的朋友,即便不用這樣的組合,最好也對其技術基本內容有所瞭解,我想對思路擴充套件是非常有好處的。

  10. Netty,NodeJs,Vertx和非同步化趨勢

  Netty的領導者和Mina的主力開發者TrustLee,是一個說話慢條斯里的韓國人。面試時問我一個關於volatile問題,雙方都覺得非母語很彆扭,所以就都簡單表達一下就算。可我沒想到這個同齡的開發人員,日後對Java在網際網路公司的地位提升,起到這麼大的作用,這個專案就是Netty。我們都知道Java非同步集合庫的作者DougLea的功勞,Nio1代,對於Socket的非同步化還不是很完善,即便是Nio2,工作重心還是檔案系統的非同步化處理,網路層的非同步化設計逐步加強改進。因為Java的設計理念,正交化,介面堆疊,底層功能平臺統一化等給非同步分散式網路框架留出足夠的空間去發揮,Netty,Mina,Grizzly等專案紛紛出現。Twitter宣佈從Ruby轉向Scala,並使用Netty讓其大紅大紫。

  所謂非同步網路框架,就是對網路層呼叫,進行非同步化,並進行介面封裝,使得容易理解和使用。非同步能力還是通過Java虛擬機器現有功能實現的,通過對資料流的處理和狀態感知來進行處理,而不是傳統的阻塞式的收發訊息。這個符合我們生活中的感受,當你訂票時,你會打電話告訴你需要什麼,說訂好票給我電話,然後你就去做別的事情,直到訂票員通知你訂好了來支付取票再進行下一步操作,如果訂票是同步的,那你就要一直等待訂票完成,遇到春運可能會搭上整天的時間。

  為什麼非同步網路框架也受到重視,答案也是網際網路,數以億計的請求點選湧來時,傳統的webserver頂不住了,採用一個執行緒服務一個請求模型的webserver,無法承受這麼大的資料訪問,特別對於Java這樣的吃記憶體語言,一個請求佔用了一個執行緒,同時也佔用了相對應的若干資源。用企業應用的設計的整個架構面對網際網路級別的應用時,有點崩潰的感覺。解決高併發大量請求的途徑是高吞吐量加上可擴充套件的軟體架構。非同步化可以提升吞吐量,就和銀行的排隊機一樣,顧客來了得到排隊服務,當有可用的櫃檯服務時會主動通知顧客,我們可以設想,即使有再多的顧客,也可以通過增加業務櫃檯,少許增加排隊機和少量人工協調處理來解決。

  NodeJs是一個非同步化的基於Javascript的開發框架,是當前的明星技術,符合了一些當前開發需求,如非同步化,前端Js技術廣泛應用,Js引擎能力極大提升,Nosql的火爆,元件構建模式變化等。利用Js語言函數語言程式設計能力,Js開發人員可以很輕鬆的利用已有的元件開發後端應用,前端可以直接用瀏覽器處理Js,別忘了Js是瀏覽器唯一能統一識別的指令碼語言,或者用JQuery,AngularJS等流行框架,世界很清淨,都是Js。

  但我們需要了解在常駐記憶體服務型程式方面,Java等語言佔有極大優勢,Java社群很快出現了和NodeJs有相同設計思路的專案,Vertx就是其中的優秀代表。它充分借鑑了NodeJs和Erlang/OTP Actor模型的優秀設計,利用分散式訊息機制進行物件間通訊,利用Netty進行網路非同步操作,方法呼叫倡導非同步呼叫,有自己的模組化機制。這樣,Java社群出現了和NodeJs競爭的技術框架,良好使用,可以解決大規模網際網路應用的需求。

  Java領域的非同步化趨勢可以說剛剛開始,我們看到Servlet和EJB都加入非同步支援,Spring的Reactor,JBoss的undertow,隨著Java8對函式語言能力的增強,可以預見又會有叢多的專案產生。我關注著非同步化趨勢和JavaEE開發方式的融合之路,相信那是Web開發的明天。

相關文章