Java叢集--大型網站是怎樣解決多使用者高併發訪問的
Java叢集--大型網站是怎樣解決多使用者高併發訪問的
時間過得真快,再次登入部落格園來寫博,才發現距離上次的寫博時間已經過去了一個月了,雖然是因為自己找了實習,但這也說明自己對時間的掌控能力還是沒那麼的強,哈哈,看來還需不斷的努力啊!(這裡得特別說明一下本人面試的一些感受:做我們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能減輕這種負擔,但對於資料量大的還是有一定影響的,而且資料庫的主從部署也可以防止因某個資料庫伺服器的掛掉而丟失使用者的資訊。
一家之言,歡迎拍磚。