做一個好的社區論壇一直是我的理想,BBS-CS從1.0到現在的5.0用了2年時間,5.0在技術上、性能上都已經基本穩定,屆此想對BBS-CS的開發思想、技術做一個說明。
在2000
年的時候,我的個人網站“愛情工作室”就是使用我自己的寫的論壇,當時是用PHP,功能上比較簡單,主要是為了網站使用,后來我想把社區論壇單獨拿出來,
并且愛情工作室網站也只剩下了社區這一部分,所以就開始用PHP按照網易社區結構寫了BBS-CS PHP
1.0的版本,后來這個版本一直沒有更新,但JSP版BBS-CS
1.0到3.0的數據結構都是從PHP版本發展來的,2000年底我開始用JAVA,2001年就寫了BBS-CS1.0,后來出了2.0,1.0、
2.0的安裝都不是很方便,并且SQL都是在JSP中,結構不好,2002年我寫了BBS-CS3.0,此時數據庫操作已經用JavaBean來封裝,但
是3.0的性能非常不好,2003年初我寫了4.0,4.0的結構已經發生了完全的變化,主要是適應多種數據庫和數據庫訪問均衡處理,性能大大增強,并且
BBS-CS定名為“天乙社區”,今年下半年我寫了5.0,5.0采用了Struts的框架,國際化內核,同時支持集群運行,全文檢索等等。
有人可能會拿BBS-CS和Jive來比較,覺得BBS-CS是小兒科,但我想BBS-CS的設計模式雖然沒有Jive那么復雜,但是在國際化、實用性、性能等方面并不差。
一、數據庫設計
BBS
-CS從4.0開始,數據庫結構發生了根本的變化,主要是對數據表作了負載均衡的處理,即一個功能不是使用一張表,而是使用多張同樣結構的表,比如存放帖
子的表有20張,這樣做的目的是為了將數據庫的查詢壓力分散到不同表中,其實道理很簡單,如果一張表中存放100萬條記錄,和100張表,每個表存放1萬
條記錄,查詢效率是完全不一樣的。具體程序中,比如一個版區的帖子往那個表中插,是由算法來實現的,算法會保證某個版區的帖子只會往某一個表中插入。
二、分頁處理
BBS
-CS4.0和5.0都是支持多數據庫的,現在支持的數據庫有Mysql、Oracle和SQL
Server,在分頁處理上確實要花一些功夫,以前我看過很多關于分頁的技術資料,處理分頁的方法主要是有幾個:1、用JDBC的本身特性,將數據全部取
出,然后根據頁碼,每頁記錄數,對查詢出的數據集的數據滾動,這個方法比較簡單、通用,但是性能極差,如果一個百萬級的數據表,將耗費巨大的系統資源,甚
至宕機;2、和第一種比較類似,但不是查出所有數據,只查出數據的主鍵,對主鍵滾動,然后根據主鍵再次查找相對應的數據,產生集合,這種方法也是EJB中
實體Bean查詢數據的方法,但依然存在性能問題,因為數據過多的時候主鍵數據集也很大,而來用主鍵插找數據的是后又進行了多次數據庫的執行操作,性能降
低。在多種分頁方法比較之后,BBS-CS還是決定采用數據自身特有的SQL語句來進行分頁,比如Mysql使用limit,Oracle使用
rownum,SQL
Server使用Top,分頁類是一個抽象類,每種數據庫的分頁實現方法都去繼承這個抽象類,然后用一個工廠方法根據系統配置文件來產生分頁類的實例,采
用這樣的分頁方法,能都達到最佳的分頁查詢效率。
三、系統配置文件
BBS-CS5.0的系統配置文件用了一個XML
文件,在4.0的時候,系統的配置文件是采用properties文件來解決,后來我覺得properties的文件還是有很大的局限性,比如,不方便進
行有數據庫結構的數據進行配置,后來覺得XML文件是一個絕佳的方案,難怪現在很多產品的配置文件都是XML的:),對于XML文件的解析,BBS-CS
采用了jdom,jdom就是java+dom(詳細資料http://www.jdom.org),一個很方便的處理XML的軟件包,在BBS-CS種對jdom的運用也不復雜,主要是用來解析bbscs.xml這個配置文件。系統解析bbscs.xml文件后,將這些系統信息保存在靜態變量中,以供系統其他程序隨時調用。
四、國際化與資源文件
JAVA
本身就是國際化的內部采用了Unicode的編碼格式,而Struts的框架,更方便了國際化的應用,Struts會根據瀏覽器的Locale,自動調取
相應的properties資源文件,在BBS-CS就是定義的app.peoperties文件,BBS-CS只定義了中文的資源包,即
app_zh_CN.properties文件,當然只要將這個文件翻譯成日文、韓文等等其他國家文字,即可實現BBS-CS多語言瀏覽。當然只有瀏覽多
語言是不行,數據的保存也必須是通用的格式,BBS-CS采用了UTF-8的編碼格式的保存數據,以解決多語言的問題,關于Unicode、UTF-8編
碼格式的資料、原理大家可以在網上查找資料,我在這里不多做講解了。
五、編碼問題
在(四)中講了國際化問題,但是如
果不作處理,對中文顯示處理都會有問題,要對app_zh_CN.propertie進行native2ascii的轉換,這個命令是在jdk/bin下
的,之后我們要做一個Servlet的過濾器,對所有的request對象進行編碼的轉換,
com.laoer.bbscs.servlet.EncodingFilter就是BBS-CS的過濾器,它對request的編碼格式進行了處理,定
義為了UTF-8的編碼格式。以前網上在看到過的一些文章上說,采用Servlet過濾器會有性能的下降,在我使用的感覺上來說,問題倒不是很大。
六、集群與Session處理
BBS
-CS5.0設計的時候考慮到了集群的應用,因為隨著系統訪問量和數據的不斷增長,單臺服務器是很難支撐的,所以要求系統能夠用多臺服務器來運行,跨服務
器的Session就是一個很大的問題,大家都知道Session是生存與一個應用中的,跨應用,Session必然不能共享,現在JSP容器,包括
Weblogic、Resin、Tomcat都可以進行集群應用,但是配制起來可能比較復雜,所以BBS-CS實現了自己的集群運用方案。實現的原理比較
簡單,主要是涉及了網絡編程,在JAVA中,對象只要implements了java.io.Serializable這個接口,即可實現串行化,便可以
在網絡中傳輸,BBS-CS就是把需要在網絡中傳輸的Session對象進行串行化,在多個服務器之間進行通訊,以達到服務器之間的Session同步,
同時對于幾臺服務器的訪問是負載均衡的。
Session實現,BBS-CS在單服務器配制下是采用了應用的Session,而在機群方式下,
是建立了自己的Session列表,Session是一個靜態的HashTable,每個用戶在登陸的時候會產生一個隨機的sid,這個sid就是
HashTable的key,而value則是一個HasMap,保存需要的對象。系統在運行期間會根據配置文件的Session超時時間定時對超時的
Session進行清理。
七、靜態變量與線程運用
為了減少對數據庫的訪問,系統很多地方使用了靜態變量來儲存數據,
比如,版區列表和信息是系統需要頻繁訪問的,如果每次都從數據庫中讀取,消耗是很大的,BBS-CS采用的方法是,一次性將數據庫讀出,放在一個靜態的列
表里(HashTable),以后再訪問則從靜態列表中取,而不是從數據庫中取,如果版區信息發生變化,只要刷新這個靜態變量就行了。
通常在
B/S結構下,系統的定時操作是比較困難的,因為B/S結構的軟件是瀏覽器事件驅動的模型,而不是服務器事件驅動,在Unix/Linux下,通常是寫一
個腳本,然后用Crontab來跑,在win下可能就要用VB/VC/Delphi來寫一個定時程序了。BBS-CS必須要做到跨品臺和通用性,而線程和
Sevlet提供很好的方法,一個web應用,可以在啟動的時候按順序的執行Servlet程序(在web.xml文件中定義),在Servlet中就可
以啟動一個線程,這個線程定時執行、休眠,便可以達到定時運行程序的目的,在BBS-CS中,清除超時Session、游客等等都是采用了線程定時執行的
方式。
posted on 2007-06-17 15:40
OMG 閱讀(711)
評論(0) 編輯 收藏 所屬分類:
Hibernate 、
Spring 、
Struts 、
WEb編程 、
<項目>系統構架