http://kb.cnblogs.com/page/537914/
2016.01
之前做日志收集模塊時,用到flume。另外也有的方案,集成kafaka來提升系統(tǒng)可擴(kuò)展性,其中涉及到消息隊(duì)列
當(dāng)時自己并不清楚為什么要使用消息隊(duì)列。
而在我自己提出的原始日志采集方案中不適用消息隊(duì)列
時,有幾個基本問題:1. 日志文件上傳過程,有個基本的生產(chǎn)者-消費(fèi)者
問題;2. 另外系統(tǒng)崩潰時,數(shù)據(jù)丟失的處理問題。
今天,幾位同事再次談到消息隊(duì)列
這么個東西,很NB的樣子,我也想弄清楚,OK,搞起。
什么是消息隊(duì)列
消息隊(duì)列(Message Queue,簡稱MQ),從字面意思上看,本質(zhì)是個隊(duì)列,F(xiàn)IFO先入先出,只不過隊(duì)列中存放的內(nèi)容是message
而已。其主要用途:不同進(jìn)程Process/線程Thread之間通信。為什么會產(chǎn)生消息隊(duì)列
?這個問題問的好,我大概查了一下,沒有查到最初產(chǎn)生消息隊(duì)列的背景,但我猜測可能幾個原因:
- 不同進(jìn)程(process)之間傳遞消息時,兩個進(jìn)程之間耦合程度過高,改動一個進(jìn)程,引發(fā)必須修改另一個進(jìn)程,為了隔離這兩個進(jìn)程,在兩進(jìn)程間抽離出一層(一個模塊),所有兩進(jìn)程之間傳遞的消息,都必須通過
消息隊(duì)列
來傳遞,單獨(dú)修改某一個進(jìn)程,不會影響另一個; - 不同進(jìn)程(process)之間傳遞消息時,為了實(shí)現(xiàn)標(biāo)準(zhǔn)化,將消息的格式規(guī)范化了,并且,某一個進(jìn)程接受的消息太多,一下子無法處理完,并且也有先后順序,必須對收到的消息進(jìn)行排隊(duì),因此誕生了事實(shí)上的
消息隊(duì)列
;
不管到底是什么原因催生了消息隊(duì)列
,總之,上面兩個猜測是其實(shí)際應(yīng)用的典型場景。
為什么要用
切合前一部分猜測的消息隊(duì)列
產(chǎn)生背景,其主要解決兩個問題:
- 系統(tǒng)解耦:項(xiàng)目開始時,無法確定最終需求,不同進(jìn)程間,添加一層,實(shí)現(xiàn)解耦,方便今后的擴(kuò)展。
- 消息緩存:系統(tǒng)中,不同進(jìn)程處理消息速度不同,MQ,可以實(shí)現(xiàn)不同Process之間的緩沖,即,寫入MQ的速度可以盡可能地快,而處理消息的速度可以適當(dāng)調(diào)整(或快、或慢)。
下面針對系統(tǒng)解耦、消息緩存兩點(diǎn),來分析實(shí)際應(yīng)用消息隊(duì)列
過程中,可能遇到的問題。虛擬場景:Process_A通過消息隊(duì)列MQ_1向Process_B傳遞消息,幾個問題:
- 針對MQ_1中一條消息message_1,如何確保Process_B從MQ_1中只取一次message_1,不會重復(fù)多次取出message_1?
- 如果MQ_1中message_1已經(jīng)被Process_B取出,正在處理的關(guān)鍵時刻,Process_B崩潰了,哭啊,我的問題是,如果重啟Process_B,是否會丟失message_1?
不要著急,閱讀了下面的簡要介紹后,水到渠成,上面幾個問題就可以解決了。 消息隊(duì)列有如下幾個好處,這大都是由其系統(tǒng)解耦和消息緩存兩點(diǎn)擴(kuò)展而來的:
- 提升系統(tǒng)可靠性:
- 冗余:Process_B崩潰之后,數(shù)據(jù)并不會丟失,因?yàn)镸Q多采用
put-get-delete
模式,即,僅當(dāng)確認(rèn)message被完成處理之后,才從MQ中移除message; - 可恢復(fù):MQ實(shí)現(xiàn)解耦,部分進(jìn)程崩潰,不會拖累整個系統(tǒng)癱瘓,例,Process_B崩潰之后,Process_A仍可向MQ中添加message,并等待Process_B恢復(fù);
- 可伸縮:有較強(qiáng)的峰值處理能力,通常應(yīng)用會有突發(fā)的訪問流量上升情況,使用足夠的硬件資源時刻待命,空閑時刻較長,資源浪費(fèi),而
消息隊(duì)列
卻能夠平滑峰值流量,緩解系統(tǒng)組件的峰值壓力;
- 提升系統(tǒng)可擴(kuò)展性:
- 調(diào)整模塊:由于實(shí)現(xiàn)解耦,可以很容易調(diào)整,消息入隊(duì)速率、消息處理速率、增加新的Process;
- 其他:
- 單次送達(dá):保證MQ中一個message被處理一次,并且只被處理一次。本質(zhì):get獲取一個message后,這一message即被預(yù)定,同一進(jìn)程不會再次獲取這一message;當(dāng)且僅當(dāng)進(jìn)程處理完這一message后,MQ中會delete這個message。否則,過一段時間后,這一message自動解除被預(yù)訂狀態(tài),進(jìn)程能夠重新預(yù)定這個message;
- 排序保證:即,滿足隊(duì)列的FIFO,先入先出策略;
- 異步通信:很多場景下,不會立即處理消息,這是,可以在MQ中存儲message,并在某一時刻再進(jìn)行處理;
- 數(shù)據(jù)流的階段性能定位:獲取用戶某一操作的各個階段(通過message來標(biāo)識),捕獲不同階段的耗時,可用于定位系統(tǒng)瓶頸。
參考來源
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點(diǎn)擊舉報。