最近在玩RabbitMQ切黔,前面的博客已經(jīng)對于RabbitMQ這一消息隊(duì)列軟件的安裝做了說明瞎颗,感覺該說一說理論概念上的東西了魄藕,下面就叨叨一下關(guān)于消息隊(duì)列相關(guān)的原理概念颤专。
什么是消息隊(duì)列
那么什么是消息列呢,百度百科給出的答案是:
“消息隊(duì)列”是在消息的傳輸過程中保存消息的容器逮光。
什么是消息
“消息”是在兩臺(tái)計(jì)算機(jī)間傳送的數(shù)據(jù)單位代箭。消息可以非常簡單,例如只包含文本字符串涕刚;也可以更復(fù)雜嗡综,可能包含嵌入對象。
消息被發(fā)送到隊(duì)列中杜漠〖埃“消息隊(duì)列”是在消息的傳輸過程中保存消息的容器。消息隊(duì)列管理器在將消息從它的源中繼到它的目標(biāo)時(shí)充當(dāng)中間人驾茴。隊(duì)列的主要目的是提供路由并保證消息的傳遞盼樟;如果發(fā)送消息時(shí)接收者不可用,消息隊(duì)列會(huì)保留消息锈至,直到可以成功地傳遞它晨缴。
消息隊(duì)列就是一個(gè)消息的鏈表」埃可以把消息看作一個(gè)記錄喜庞,具有特定的格式以及特定的優(yōu)先級(jí)诀浪。對消息隊(duì)列有寫權(quán)限的進(jìn)程可以向消息隊(duì)列中按照一定的規(guī)則添加新消息;對消息隊(duì)列有讀權(quán)限的進(jìn)程則可以從消息隊(duì)列中讀走消息延都。消息隊(duì)列是隨內(nèi)核持續(xù)的雷猪。
什么是消息隊(duì)列
找到一篇有趣的文章:https://github.com/jasonGeng88/blog/blob/master/201705/MQ.md
有一天,產(chǎn)品跑來說:“我們要做一個(gè)用戶注冊功能晰房,需要在用戶注冊成功后給用戶發(fā)一封成功郵件求摇。”
小明(攻城獅):“好殊者,需求很明確了与境。” 不就提供一個(gè)注冊接口猖吴,保存用戶信息摔刁,同時(shí)發(fā)起郵件調(diào)用,待郵件發(fā)送成功后海蔽,返回用戶操作成功共屈。沒一會(huì)功夫,代碼就寫完了党窜。驗(yàn)證功能沒問題后拗引,就發(fā)布上線了。
線上正常運(yùn)行了一段時(shí)間幌衣,產(chǎn)品匆匆地跑來說:“你做的功能不行啊矾削,運(yùn)營反饋?zhàn)圆僮黜憫?yīng)太慢,已經(jīng)有好多用戶流失了豁护『呖”
小明聽得一身冷汗,趕緊回去改择镇。他發(fā)現(xiàn)挡逼,原先的以單線程同步阻塞的方式進(jìn)行郵件發(fā)送,確實(shí)存在問題腻豌。這次,他利用了 JAVA 多線程的特性嘱能,另起線程進(jìn)行郵件發(fā)送吝梅,主線程直接返回保存結(jié)果。測試通過后惹骂,趕緊發(fā)布上線苏携。小明心想,這下總沒問題了吧对粪。
沒過多久右冻,產(chǎn)品又跑來了装蓬,他說:“現(xiàn)在,注冊操作響應(yīng)是快多了纱扭。但是又有新的問題了牍帚,有用戶反應(yīng),郵件收不到乳蛾。能否在發(fā)送郵件時(shí)暗赶,保存一下發(fā)送的結(jié)果,對于發(fā)送失敗的肃叶,進(jìn)行補(bǔ)發(fā)蹂随。”
小明一聽因惭,哎岳锁,又得熬夜加班了。產(chǎn)品看他一臉苦逼的樣子蹦魔,忙說:“郵件服務(wù)這塊浸锨,別的團(tuán)隊(duì)都已經(jīng)做好了,你不用再自己搞了版姑,直接用他們的服務(wù)柱搜。”
小明趕緊去和郵件團(tuán)隊(duì)溝通剥险,誰知他們的服務(wù)根本就不對外開放聪蘸。這下小明可開始犯愁了,明知道有這么一個(gè)服務(wù)表制,可是偏偏又調(diào)用不了健爬。
郵件團(tuán)隊(duì)的人說,“看你愁的么介,我給你提供了一個(gè)類似郵局信箱的東西娜遵,你往這信箱里寫上你要發(fā)送的消息,以及我們約定的地址壤短。之后你就不用再操心了设拟,我們自然能從約定的地址中取得消息,進(jìn)行郵件的相應(yīng)操作久脯∧呻剩”
后來,小明才知道帘撰,這就是外界廣為流傳的消息隊(duì)列跑慕。你不用知道具體的服務(wù)在哪,如何調(diào)用。你要做的只是將該發(fā)送的消息核行,向你們約定好的地址進(jìn)行發(fā)送牢硅,你的任務(wù)就完成了。對應(yīng)的服務(wù)自然能監(jiān)聽到你發(fā)送的消息芝雪,進(jìn)行后續(xù)的操作减余。這就是消息隊(duì)列最大的特點(diǎn),將同步操作轉(zhuǎn)為異步處理绵脯,將多服務(wù)共同操作轉(zhuǎn)為職責(zé)單一的單服務(wù)操作佳励,做到了服務(wù)間的解耦。
哈哈蛆挫,這下能高枕無憂了赃承。太年輕,哪有萬無一失的技術(shù)啊~
不久的一天悴侵,你會(huì)發(fā)現(xiàn)所有業(yè)務(wù)都替換了郵件發(fā)送的方式瞧剖,統(tǒng)一使用了消息隊(duì)列來進(jìn)行發(fā)送。這下僅僅一個(gè)郵件服務(wù)模塊可免,難以承受業(yè)務(wù)方源源不斷的消息抓于,大量的消息堆積在了隊(duì)列中。這就需要更多的消費(fèi)者(郵件服務(wù))來共同處理隊(duì)列中的消息浇借,即所謂的分布式消息處理捉撮。
再來看一下維基百科的說明:
消息隊(duì)列(英語:Message queue)是一種進(jìn)程間通信或同一進(jìn)程的不同線程間的通信方式,軟件的貯列用來處理一系列的輸入妇垢,通常是來自用戶巾遭。消息隊(duì)列提供了異步的通信協(xié)議,每一個(gè)貯列中的紀(jì)錄包含詳細(xì)說明的數(shù)據(jù)闯估,包含發(fā)生的時(shí)間灼舍,輸入設(shè)備的種類,以及特定的輸入?yún)?shù)涨薪,也就是說:消息的發(fā)送者和接收者不需要同時(shí)與消息隊(duì)列互交骑素。消息會(huì)保存在隊(duì)列中,直到接收者取回它刚夺。 ——維基百科
解釋還是有些官方了献丑,不好理解,來個(gè)圖吧
- Producer:消息生產(chǎn)者光督,負(fù)責(zé)產(chǎn)生和發(fā)送消息到 Broker阳距;
- Broker:消息處理中心。負(fù)責(zé)消息存儲(chǔ)结借、確認(rèn)、重試等卒茬,一般其中會(huì)包含多個(gè) queue船老;
- Consumer:消息消費(fèi)者咖熟,負(fù)責(zé)從 Broker 中獲取消息,并進(jìn)行相應(yīng)處理柳畔;
消息隊(duì)列的特性
異步性
將耗時(shí)的同步操作馍管,通過以發(fā)送消息的方式,進(jìn)行了異步化處理薪韩。減少了同步等待的時(shí)間确沸。
松耦合
消息隊(duì)列減少了服務(wù)之間的耦合性,不同的服務(wù)可以通過消息隊(duì)列進(jìn)行通信俘陷,而不用關(guān)心彼此的實(shí)現(xiàn)細(xì)節(jié)罗捎,只要定義好消息的格式就行。
分布式
通過對消費(fèi)者的橫向擴(kuò)展拉盾,降低了消息隊(duì)列阻塞的風(fēng)險(xiǎn)桨菜,以及單個(gè)消費(fèi)者產(chǎn)生單點(diǎn)故障的可能性(當(dāng)然消息隊(duì)列本身也可以做成分布式集群)。
可靠性
消息隊(duì)列一般會(huì)把接收到的消息存儲(chǔ)到本地硬盤上(當(dāng)消息被處理完之后捉偏,存儲(chǔ)信息根據(jù)不同的消息隊(duì)列實(shí)現(xiàn)倒得,有可能將其刪除),這樣即使應(yīng)用掛掉或者消息隊(duì)列本身掛掉夭禽,消息也能夠重新加載霞掺。
消息隊(duì)列主要解決的問題
消息隊(duì)列主要解決了應(yīng)用耦合、異步處理讹躯、流量削鋒等問題菩彬。
信息隊(duì)列的主要應(yīng)用場景
消息隊(duì)列的主要應(yīng)用場景有四種:
應(yīng)用耦合:多應(yīng)用間通過消息隊(duì)列對同一消息進(jìn)行處理,避免調(diào)用接口失敗導(dǎo)致整個(gè)過程失斒癯拧挤巡;
異步處理:多應(yīng)用對消息隊(duì)列中同一消息進(jìn)行處理,應(yīng)用間并發(fā)處理消息酷麦,相比串行處理矿卑,減少處理時(shí)間;
限流削峰:廣泛應(yīng)用于秒殺或搶購活動(dòng)中沃饶,避免流量過大導(dǎo)致應(yīng)用系統(tǒng)掛掉的情況母廷;
消息驅(qū)動(dòng)的系統(tǒng):系統(tǒng)分為消息隊(duì)列、消息生產(chǎn)者糊肤、消息消費(fèi)者琴昆,生產(chǎn)者負(fù)責(zé)產(chǎn)生消息,消費(fèi)者(可能有多個(gè))負(fù)責(zé)對消息進(jìn)行處理馆揉;
四種應(yīng)用場景的分析將在后續(xù)更新业舍。
當(dāng)前常用的消息隊(duì)列
當(dāng)前使用較多的消息隊(duì)列有RabbitMQ、RocketMQ、ActiveMQ舷暮、Kafka态罪、ZeroMQ、MetaMq等下面,而部分?jǐn)?shù)據(jù)庫如Redis复颈、Mysql以及phxsql也可實(shí)現(xiàn)消息隊(duì)列的功能。
本人是做java中間件的沥割,正在玩RabbitMQ和ActiveMQ耗啦。之前有寫過rebbitMQ的安裝說明。后續(xù)對這兩個(gè)信息隊(duì)列進(jìn)行對比机杜。