Java集群--大型網站是怎樣解決多用戶高并發訪問的

manden 8年前發布 | 37K 次閱讀 并發 Java Java開發

來自: http://www.cnblogs.com/wanggangjia/p/5222759.html

時間過得真快,再次登錄博客園來寫博,才發現距離上次的寫博時間已經過去了一個月了,雖然是因為自己找了實習,但這也說明自己對時間的掌控能力還是沒那么的強,哈哈,看來還需不斷的努力啊!(這里得特別說明一下本人面試的一些感受:做我們IT這一行,一定要使自己精于某個領域,再不斷的去涉獵其他的領域,更重要的是學會找出各個領域的相融點,這跟我們學習書本一樣,用‘Java’和‘計算機網絡’來舉下例子,我們知道Java中的socket編程,對于面向連接的編程來說(包括我們每次在網頁上向服務器請求資源時),它的第一步就是建立雙方之間的通訊鏈路,而這個過程其實就是TCP的連接,這時就可以聯想計算機網絡中的TCP連接的三次握手,而在斷開時就可以聯想TCP斷開連接的四次揮手等等;再者就是學習每門編程語言時,要打好自己的基礎,這在面試的時候是很重要的......)

本人進入公司實習后,發現本人所在的項目組所采用的框架技術是Seam(簡單粗暴的講該框架就是JSF和EJB3的粘合劑),也許大多數的你們跟本人一樣,在學校上基本沒有聽過有這么個框架,確實,這個框架確實沒那么火,網上的資料也沒有SSH三大架構的多,但是,既然在這個項目組了,那就得做好本職工作了,于是,花了兩天的時間來先熟悉一下整體的代碼,剛好,這時客戶那邊有一個新的需求,于是,導師就把這個重任放在本人身上了(深深的感覺導師太看重本人了),于是,花了三天的時間把這個功能實現了并交付給客戶去使用,自己也因此對這個框架更加熟悉了一點。

后來,公司覺得Seam這個框架有點老了,所以就想對該項目實行底層改造,也就是因為這個契機,通過項目組成員的討論,在實現底層改造的同時,也把單機網站過渡到分布式網站,這也就是本人在本文將要講訴的內容了。

為了解決大型網站的訪問量大、并發量高、海量數據的問題,我們一般會考慮業務拆分和分布式部署。我們可以把那些關聯不太大的業務獨立出來,部署到不同的機器上,從而實現大規模的分布式系統。但這之中也有一個問題,那就是用戶如何選擇相應的機器的問題,這也被稱為訪問統一入口問題,而解決的方法是我們可以在集群機器的前面增加負載均衡設備,實現流量分發(總圖如下)。

這里得先解釋一下何為“負載均衡”,負載均衡就是將負載(工作任務、訪問請求等)進行平衡、分攤到多個操作單元(服務器、組件等)上進行執行,是解決高性能,單點故障(高可用,如果你是單機版網絡,一旦服務器掛掉了,那么用戶就無法請求了,但對于集群來說,一臺服務器掛掉了,負載均衡器會把用戶的請求發送給其他的服務器進行處理),擴展性(這里主要是指水平伸縮)的終極解決方案。

在這里,本人主要討論負載均衡設備為Nginx(至于為啥不講講F5,因為人家太貴了,不過人家比較穩定),這是一款輕量級的Web服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,具有占用內存少、并發能力強等,中國大陸使用nginx網站用戶有:百度、網易、新浪、騰訊等(該介紹來自百科)。

nginx大家可以上其 官網 去下載最新版,解壓后復制到部署目錄,對于Nginx的配置網上的資料很多,這里就不再贅述了,只總結一下Nginx使用的注意事項:

1.nginx的負載均衡配置中默認是采用輪詢的方式,這種方式中,每個請求按時間順序逐一分配到不同的后端服務器,如果后端服務器down掉,能自動剔除,但存在各個服務器的session共享問題。

2.另外一種方式是ip_hash:每個請求按訪問的ip的hash結果分配,如果訪問的IP是固定的,那么在正常情況下,該用戶的請求都會分配到后臺的同一臺服務器去處理,但是如果用戶每次請求的IP都不同呢?所以這種方式也同1的方式一樣都存在這么一個問題:session在各個服務器上的共享問題。

3.,如果集群中的服務器的性能不一,可以通過配置各個服務器的權值來實現資源利用率的最大化,即性能好的優先選擇

也許你會問,既然IP可能變化,那么用戶用頁面請求時的cookie的ID應該是確定的吧!那么我們可以用cookie_id來進行hash,然后在通過負載均衡器分發到對應的服務器上,這樣就可以解決session問題了,其實當初本人也有想到這個方案,但最后本人也放棄這個方案了,因為是根據cookid_id確實可以把該用戶的請求唯一的分發到那臺獨一無二的服務器上,那如果這臺服務器掛掉了,那么根據這種分發策略,豈不是在這服務器上請求資源的用戶都不能訪問了,你說是不是呢?

解決服務器共享session問題:使用redis來共享各個服務器的session,并同時通過redis來緩存一些常用的資源,加快用戶獲得請求資源的速度(個人比較喜歡redis,當然你們也可以使用memcache來實現,不過,memcache不能做到持久化,這樣這臺服務器一掛掉,那么所有的資源也都沒有了......)。

不過,本人覺得這樣進行集群部署,最好配上數據庫的主從部署,因為如果在集群中只分配一個數據庫服務器,那么這個系統的瓶頸將會出現在數據庫的操作上,雖然redis能減輕這種負擔,但對于數據量大的還是有一定影響的,而且數據庫的主從部署也可以防止因某個數據庫服務器的掛掉而丟失用戶的信息。

一家之言,歡迎拍磚。

 本文由用戶 manden 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!