javaweb專案高併發處理
併發是什麼,之前我覺得就是對資料的一個安全性操作,這樣理解也沒有錯,因為這是資料的併發,那麼什麼是併發呢?
併發,在作業系統中,是指一個時間段中有幾個程式都處於已啟動執行到執行完畢之間,且這幾個程式都是在同一個處理機上執行,但任一個時刻點上只有一個程式在處理機上執行。這也是我之前的理解。
現在我認為對於web系統併發是分為兩類的:1.使用者量的併發;2.資料的併發
那麼怎麼處理這兩類併發呢,在真實的專案中我也沒實踐過,僅僅整理了一下別人的成果,如下:
針對使用者量的併發處理:
1.網頁靜態化。
先說說靜態化的好處:
1.搜尋引擎優化是細節上的優化, 從網站優化來分析,搜尋引擎更喜歡靜態的網頁
2.提高了網站反映速度(或許指的是純HTML網頁,非JSP網頁)
3.靜態網頁化之網站穩定,從安全形度講,靜態網頁不宜遭到黑客攻擊,從網站穩定性來講,如果程式、資料庫出了問題,會直接影響網站的訪問,而靜態網頁就避免瞭如此情況,不會因為程式等,而損失網站資料,影響正常開啟
在第一次請求web服務時會執行如下過程:
1.客戶端傳送請求給web容器
2.web容器將jsp首先轉譯成servlet原始碼
3.web容器將servlet原始碼編譯成.class 檔案
4.web容器執行.class 檔案
5.web容器將結果響應給客戶端
所以web第一次為請求提供服務比較慢,從第二次請求開始會省略2、3兩個步驟。
在網上有看到有兩種方法做Jsp的靜態化:
1.部分文章直接用JspWriter的方式輸出jsp,我沒有經過測試,不知道這種方式效能是不是真的能提升,但是我覺得這種方式還是逃不開上面的5步,所以自我感覺沒有意義。
2.部分文章是把要輸出的jsp直接編譯用HTML的方式儲存在伺服器了,當用戶呼叫的時候不用查詢資料庫,而是直接返回該HTML頁面,這樣也省去web容器對JSP的操作
理論上確實有效果的,但是儲存的HTML檔案都是些不會變動內容,變動了還要重新儲存HTML,感覺吃力不討好的樣子。
對於所謂的靜態化,感覺做一下偽靜態化倒是個不錯的主意,不知道貓撲和天涯是採用的什麼方式去做的,或許真的有好的辦法也說不定,歡迎大家留言告訴我。
2.圖片伺服器分離
這種方式主要是減輕伺服器的壓力,基於頻寬和伺服器的處理效能的優化,當客戶端的瀏覽器解析服務端傳回來的HTML時,會遠端呼叫圖片伺服器的圖片下載,這樣就減小了主伺服器的壓力。
說到圖片的話,也要說一下圖片緩現技術了,jQuery有一個外掛lazyload.js,它可以在圖片很多的網頁中使用,當用戶滾動到哪裡時哪裡再載入圖片,可以有效的使用伺服器頻寬,使用者體驗也不錯,貌似就發現這麼一款外掛,歡迎大家給我推薦。
3.ajax非同步請求
有人說用ajax請求也能減輕伺服器的壓力,可以不用傳整個頁面給客戶端了,確實是這樣。不過我覺得也不能太依賴ajax,要看場合的使用吧,比如說新增和修改等操作還是用表單提交的好。
4.對系統做資料快取、系統負載均衡處理
資料的快取快取都是指放在記憶體裡面的,方便快速讀取而不用重新去資料庫查詢的資料。據說spring對ehchache的支援特別好,看了其它的帖子介紹,hibernate和JDBC都是能夠使用這種第三方的快取機制的,Apache也有相應的快取機制,不過沒用過,個人傾向於ehcache。
再來就是對系統做負載均衡的處理了,這一塊的話沒有什麼太多建議,因為沒有從事過,只知道概念,以後再單獨寫給大家。
5.資料庫叢集和庫表雜湊
這是針對資料庫做的資料庫伺服器叢集,資料庫叢集方面,很多資料庫都有自己的解決方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是類似的方案,您使用了什麼樣的DB,就參考相應的解決方案來實施即可,有時間再具體討論吧。
6.映象站點
映象站其實就是主伺服器系統的一個備份,除了頻寬和伺服器效能可能有差異外,其它都是一樣,而且域名也不一樣,這樣也能起到分散主伺服器壓力的效果,就是有點麻煩。
一些常用的系統架構伺服器分類:圖片伺服器,頁面伺服器,資料庫伺服器,應用伺服器,日誌伺服器等等
針對資料的併發處理:
1.在方法呼叫時使用synchronize機制。
在呼叫Java方法時,可以使用這種同步機制,只允許一個執行緒操作裡面的資料,也就不會發生髒讀,幻讀了。
2.給資料庫加鎖,利用事務的隔離級別
資料庫有各種的鎖機制,可以避免資料的併發操作,這個大概只能資料庫用得到,比如儲存過程。JDBC的預編譯PreparedStatement 只能對事務進行管理,不會鎖表的,所以若是程式碼去處理可以利用spring的事務管理機制中的隔離級別去處理了。
3.hibernate使用的是version欄位判斷。
以前做專案用的是hibernate,那時候為了防止資料的併發,就在每個bean中設計了version的欄位,當查出來的數字和要更新時的數字顯示不相同時,就說明該資料已經被其它使用者給操作了,從而判斷是否資料安全,這種方式是hibernate倡導的。
暫時知道的也就這麼多了,希望大家多提點建議讓我改進改進吧,回頭熟悉了伺服器叢集和資料庫叢集再和大家討論討論。
參考資料:
http://baike.baidu.com/view/1417314.htm?fr=aladdin
http://blog.csdn.NET/dyllove98/article/details/8588790
http://www.cmhello.com/jquery-lazyload-js.html