1. 程式人生 > >訊息佇列處理高併發

訊息佇列處理高併發

mq來將耗時比較長或者耗費資源的請求排隊,非同步處理,減輕伺服器壓力增加穩定性。
如果是高併發的實時請求,我個人覺得不適用這個方案。如果是為了高併發,我覺得應該朝解決高併發的方向考慮。叢集、分散式、動靜分離、資料庫讀寫分離之類的。

web的話,只能客戶端頁面輪訓處理結果。
因為,據我個人瞭解啊,現在web沒有成熟的向客戶端推送處理結果的技術。或者是我沒弄好,如果有知道的,還望提點下。

 

把客戶行為變為非同步,就是提交後,只通知收到請求,需要客戶再提交查詢請求,檢視結果


首先,我們來說一下為什麼要使用MQ(訊息佇列)?

主要原因是由於在高併發的環境下,由於伺服器來不及同步處理,請求往往會發生堵塞的現象,比如說大量的增加、修改(

insertupdata)之類的請求同事到達mysql,直接導致無數的行鎖,表鎖、甚至最後請求堆積過多,從而觸發too many connections錯誤。通過使用訊息佇列MQ,我們就可以非同步處理請求,從而緩解系統的壓力。

 

訊息阻塞佇列現在比較流行的RabbitMQredisMQactiveMQ~!也就是專業訊息中介軟體,一般用於處理高併發的問題~

這裡面 RabbitMQredisMQ我沒有研究過,我只瞭解過activeMQ~!在activeMQ中處理高併發問題時。我們首先就要知道是什麼的高併發。消費者,還是生產者。

 

首先,我來說一下消費者的高併發處理,因為這個簡單、好說一些

~!它一般產生的原因是在activeMQ的佇列中積壓了資料的話,我們在spring中啟動了listen但是(讀音重一點,停頓一下)我們在activeMQ的監控網頁裡面看到只有一個consumer(消費者)在執行,這時候就得說一說,activeMQ的執行機制了。它裡面也就是activeMQ是預設將 取1000條資料交由一個consumer處理的,下一個1000才是由另一個去處理的。所以吧這個預設的值調一下就行了~!一般我們是在客戶端的連結url裡面,修改(tcp://ipaddr:61616?jms.prefetchPolicy.all=2),這樣就公平分配了~

 

這時候我們來談一談怎麼去解決高併發的問題

~!這裡就要說到部署ActiveMQ了,其實說白了就是擴充套件你的應用程式,我簡單的在網上查過一些資料,知道有差不多,大概有3中處理方式。垂直擴充套件、橫向擴充套件、傳輸負載分流

 

1、垂直擴充套件

a) 垂直擴充套件簡單來說就是一種用於增加單個ActiveMQ代理連線數的技術,這裡還得順便提一下,因為增加了代理連結數,所有,他的負載能力也增強了。一般預設的情況下,activeMQ是使用的阻塞IO來處理傳輸連結的,也就是同步io,一個連結分配一個執行緒,所有很明顯的,我們只需要吧同步io換成非同步io就行了,也就是非阻塞ioNIO)就行了,在ACtiveMQ配置檔案中配置,至於具體的怎麼配的,我不太記得了,網上有資料~

b) 除了同步Io換非同步io的方式。我們還可以根據每一個客戶端的連線搞一個訊息來分發執行緒,具體的好像是在系統引數(org.apache.activemq.UseDedicatedTaskRunner)設定為false來設定activeMQ使用將搞一個執行緒池,不過用這個方法的話,有個前提,就是需要有足夠的記憶體來執行。這裡還有隱藏的一個問題,就是cpu的負載,就是如果你在使用Open-Wire協議的格式訊息。那麼最好是關閉tight encoding選項(這裡留個疑問給面試官。如果問,為什麼會佔用cpu很多,和怎麼關~!就答:因為這個東西開啟的話,cpu佔用就太多了,至於怎麼關,也是在系統引數檔案裡面配置)

2、橫向擴充套件

a) 垂直擴充套件是一種單獨的代理 ,第二個方式就是橫向擴充套件也就是我們所說的使用代理網路來增加應用程式的代理數量,它的原理就是利用網路自動傳遞訊息給所有網際網路的具有對訊息感興趣的消費者的代理,所以,我們就可以配置客戶端連結到一個代理的叢集,隨機的選擇叢集中的一個代理來連結。(這裡留個疑問給面試官。如果問怎麼弄?就回答:網際網路嘛,我們通過url的引數配置就行了。)

3、傳輸負載分流

a) 而關於第三個方法,客戶端的傳輸負載分流,就是前面兩個(垂直和水平)的混合負載分流的方案,但是這裡通常不適用代理網路,因為客戶端程式會決定將哪個負載傳送到哪個代理上、客戶端程式需要維護多個jms連結,並且決定哪個jms連線應該用於哪個訊息的目的地。

b) 這裡有一個好處,就是由於沒有直接使用網路連線,我們就降低了代理過量的訊息轉發,不需要進行額外的負載均衡處理。


http://blog.csdn.net/truong/article/details/73718621?readlog(詳細的文章)