java web的併發處理

併發是什麼,之前我覺得就是對數據的一個安全性操作,這樣理解也沒有錯,因爲這是數據的併發,那麼什麼是併發呢?

併發,在操作系統中,是指一個時間段中有幾個程序都處於已啓動運行到運行完畢之間,且這幾個程序都是在同一個處理機上運行,但任一個時刻點上只有一個程序在處理機上運行。這也是我之前的理解。


現在我認爲對於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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章