SpringSide是個好東西,對我來說,它的好主要體現在兩個方面:一、它提供了一個敏 捷開發的框架,省去了我自己整合Spring、Hibernate、Struts、ActiveMQ等等開源組件的 時間,而且還是最佳實踐;二、它指導了我的學習目標,在SpringSide中整合的各種組件, 都是在同一類組件中最優秀的,而且要想熟練使用這些組件,都必須對它們進行深入的系統 的學習。
本來以為我會在SpringSide開發實戰系列中寫更多的文章,但是寫到現在,我認為應該 要寫結局了,為什麼呢?因為在使用SpringSide進行項目開發的過程中,我越來越感覺到項 目絕對不是各種組件的簡單堆砌,而是程序員要不斷有自己的想法和創意,並能夠抽象到一 個高度。這也正是為什麼我的文章從第一篇到第八篇越來越偏離SpringSide的核心了。在這 裡,我主要想談談程序員的境界。以下觀點純屬個人看法,歡迎大家探討。
第一層境界:從不能到能。
可以這麼說,早在7年前我就已經熟練掌握C語言、Visual FoxPro數據庫、HTML、CSS和 JavaScript,C語言和Visual FoxPro是學校教的,HTML、CSS和JavaScript是自學的,同時 ,我還自學了Flash動畫制作和Photoshop圖像處理。但是,我那時候還不知道應用程序開發 ,學的這些東西無非就是好玩,偶爾參加一次學校主辦的網頁設計大賽而已。
我開發的第一個應用是《銀符英語在線》,使用的是ASP + SQL Server 2000,時間是 2004年,那時我剛考過軟件設計師(原高級程序員),有人找我做程序,他說想做一個英語 四六級的在線考試系統,問我能不能做到,我毫不猶豫就說能。我想我確實是具有軟件設計 方面的天賦,用了一個星期設計出數據庫,再用一個星期寫了一個Demo,一下子就把他征服 了,於是,他當老板,我當程序員,一起進行在線英語考試方面的開發。
在這段時間,我覺得我不折不扣就是處於這第一層境界。JScript我早已是滾瓜亂熟, ASP教程更隨處可得。在這段時間裡,我用全JScript代碼實現了用戶認證和權限管理,用 Visual C++寫了個COM組件進行數據的加密和解密,還在網上到處搜索文件上傳和動態圖片 生成方面的解決辦法。當時,我覺得我的開發過程充實而滿足;現在看來,我只不過是一個 重復發明輪子的傻冒。
在10個月的時間裡,我把這個程序從1.0版開發到3.0版,功能上進行了不少升級。但是 我認為升級最大的還是我的技術,我盡我最到的能力將代碼與網頁分離,盡我最到的能力減 少代碼的重復,甚至已經基本做到使用模式來讓程序更加容易擴充和維護。我所做的一切, 與現代的一些Web開發框架已經不謀而合。但是,以我當時的內力,確實沒有辦法將之抽象 為一個框架。我的程序中依然充滿了意大利面條式的代碼,而且在在線人數多的時候,網頁 會慢得象蝸牛爬。
第二層境界:從能做到做得漂亮
2005年,我開始接觸Java,以我的基礎,自然是很快就學會了Java的語法並進軍J2EE。 我覺得Java開源世界給了我不少能量,在這兩年裡,我的進步速度是呈指數式的。以我現在 的水平,僅使用JSP和Servlet,已經足以解決絕大部分的需求。然而,僅使用JSP和Servlet 就是全部嗎?
這個時候,我們不僅僅要能夠完成應用程序的編寫,更重要的要讓應用程序便於維護和 便於擴充。這時候,沒有足夠的抽象能力是不夠的。要能夠理解和應用分層架構,要知道 MVC、IoC、AOP、ORM,要了解聲明式事務處理,還要學會最流行了AJAX。所有的這一切,不 僅能夠讓我們的應用便於維護,合理使用各開源組件還能加快開發的速度,但是最重要的, 它們能使我們的應用充滿藝術的美感。
在SpringSide社區,現在最流行的是Acegi,這也是對安全與權限功能的一種抽象。本來 我也想寫一篇Acegi方面的文章,但是cac寫的文檔是在是太完美、太經典了,我無法超越。 我們應該讓我們的應用盡量向Acegi靠攏,因為,它代表的就是安全與權限領域的最佳實踐 。
第三層境界:從程序員到架構師
架構師可以干什麼?如何讓應用在性能,伸縮性,擴展性、可靠性,容災,可恢復性, 可管理性等方面做到最好,就是架構師的職責,同時,架構師要能夠把握軟件開發的整個周 期。由於我還只是一個程序員,也沒有精力去學習架構師方面的只是,因此上面的論述可能 不准確。但是,作為一個程序員,上升到一個境界之後,確實應該考慮編碼之外的東西了。
舉例說明,cnblogs的博客程序算式比較完善的了,我個人對站長dudu也是充滿了仰慕。 cnblogs的1.0Beta2版本我也下載得有,本打算使用它建一個自己的博客網站,但是卻不行 ,因為它在性能,伸縮性,擴展性方面都達不到我的要求。
不信?看看現在www.cnblogs.com吧,注冊用戶已經2萬多了,速度也是越來越慢,經過 我一nslookup,發現它還只是一台主機在運行,而www.tianya.cn則是一個服務器集群。如 下圖:
造成這個問題的原因,主要就是架構的問題。cnblogs是基於.net的,.net運行於IIS之 上,而IIS又是那麼的簡單,更本不具備配置Cluster的功能。而cnblogs的程序在設計的時 候也沒有往集群方面考慮,甚至是想多配置幾個數據庫都是困難的。
解決網站性能的辦法有幾種,一是向上擴展,也就是不斷增加服務器的CPU和內存,但是 這種擴展價格非常昂貴;二是向外擴展,也就是多增加幾台廉價的Web服務器和數據庫服務 器,但是由於cnblogs在設計的時候沒有考慮到集群功能,就必須得重構所有的代碼,這個 工作量實在是太大了;三是垂直分割,也就是目前博客園所采用的方法,就是讓一台主機負 責.net博客,一台主機負責java博客等等,把不同的應用分開。這樣帶來的負面影響是我們 就沒有辦法在同一個博客上面同時寫.net、java、c++方面的隨筆了,這確實讓我感覺不爽 ,此外,在.net領域這樣訪問量大的領域,一樣會使服務器不堪重負。
我不能讓我的程序重蹈覆轍,因此,在架構階段就應該考慮到Cluster,考慮到負載均衡 ,考慮到可擴充性,並同時使用水平分割策略。水平分割策略和垂直分割策略不同,是讓每 一個Web服務器都應該能夠使用程序的所有功能,而讓不同的用戶使用不同的服務器,比如 id為0-10000的用戶和www1.cnblogs.com交互,10001-20000的用戶和www2.cnblogs.com交 互,等等,如下圖所示:
這個時候,服務器www.cnblogs.com作為負載均衡服務器,它根據登錄用戶的ID將該用戶 請求重定向到www1.cnblogs.com或者www2.cnblogs.com,對於匿名用戶,它把用戶請求隨機 重定向到www1.cnblogs.com或者www2.cnblogs.com。
同時,為了能夠讓負載均衡服務器能夠根據不同的用戶來重定向到不同的Web服務器,又 要讓每個Web服務器上的應用都能夠得到所有各個數據庫服務器數據的總的索引,需要有一 個索引數據庫服務器,如下圖:
此外,我們還應該讓Web服務器和數據庫服務器可以動態增加,也就是當某一個服務器負 載到達極限時,我們可以添加一台服務器,只需要修改配置文件即可,無需更改代碼,如下 圖:
同時配合使用動態頁面靜態化技術,靜態化後的html頁面和圖片文件都保存在Web服務器 上,此時Web服務器有同時擔當了緩存服務器的功能。當達到IO瓶頸的限制後,又可以通過 服務器加大內存或為服務器配置SAN(存儲區域網絡)來解決問題。
好了,SpringSide系列的文章就寫這麼多吧。期待SpringSide 2.0正式版的發布。我會 把它用到實際的項目開發中。