是一個(gè)消息的鏈表,是一個(gè)異步處理的數(shù)據(jù)處理引擎。
公司主營業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出祁陽免費(fèi)做網(wǎng)站回饋大家。
PS:可以理解為在redis的list列表中存放消息數(shù)據(jù),然后按照排隊(duì)方式先進(jìn)先出(左進(jìn)右出;右進(jìn)左出)
主要應(yīng)用一些延遲或異步操作的場景
比如:發(fā)送郵件、發(fā)送短信、視頻轉(zhuǎn)碼、圖片轉(zhuǎn)碼、日志存儲(chǔ)、導(dǎo)入數(shù)據(jù)等
在發(fā)送郵件或者短信,我們不希望程序一直停留,等待發(fā)送成功才相應(yīng),而是異步進(jìn)行處理,即:將待發(fā)送的郵件數(shù)據(jù)添加到消息隊(duì)列中,然后按照排隊(duì)先后進(jìn)行異步發(fā)送郵件。
不僅能夠提高系統(tǒng)的負(fù)荷,還能夠改善因網(wǎng)絡(luò)阻塞導(dǎo)致的數(shù)據(jù)缺失
這個(gè)可以理解為:異步處理數(shù)據(jù),不會(huì)一次性給服務(wù)器太多壓力,并且不直接操作數(shù)據(jù)庫,減少了數(shù)據(jù)庫的壓力;并且若在網(wǎng)絡(luò)阻塞時(shí),若已經(jīng)添加到消息隊(duì)列中,那么這些數(shù)據(jù)會(huì)正常執(zhí)行,不會(huì)造成丟失
整體思路:
前面提到消息隊(duì)列,就相當(dāng)于到銀行窗口排隊(duì),先到的叫號(hào)入隊(duì)(加入到redis消息隊(duì)列),然后排到了則根據(jù)相應(yīng)的叫號(hào)出隊(duì)。
redis的一些特點(diǎn):
redis設(shè)計(jì)用來做緩存的,但是由于它自身的某種特性使得它可以用來做消息隊(duì)列,它有幾個(gè)阻塞式的API可以使用,正是這些阻塞式的API讓其有能力做消息隊(duì)列;另外,做消息隊(duì)列的其他特性例如FIFO(先入先出)也很容易實(shí)現(xiàn),只需要一個(gè)list對象從頭取數(shù)據(jù),從尾部塞數(shù)據(jù)即可;redis能做消息隊(duì)列還得益于其list對象blpop brpop接口以及Pub/Sub(發(fā)布/訂閱)的某些接口,它們都是阻塞版的,所以可以用來做消息隊(duì)列。
使用redis的lpush/rpop (rpush/lpop) 命令 簡單實(shí)現(xiàn)左進(jìn)右出 或 右進(jìn)左出 的list列表。
然后需要開啟一個(gè)線程任務(wù)或者定時(shí)任務(wù)或者輪詢方式,不停的調(diào)用rpop方法查看List中是否有待處理消息。
缺點(diǎn):每調(diào)用一次都會(huì)發(fā)起一次連接,這會(huì)造成不必要的浪費(fèi)。
1)、如果生產(chǎn)者速度大于消費(fèi)者消費(fèi)速度,消息隊(duì)列長度會(huì)一直增大,時(shí)間久了會(huì)占用大量內(nèi)存空間。
2)、如果睡眠時(shí)間過長,這樣不能處理一些時(shí)效性的消息,睡眠時(shí)間過短,也會(huì)在連接上造成比較大的開銷。
將方案一中的lpop、rpop命令改為使用blpop(左出)、brpop(右出)
這個(gè)指令只有在有元素時(shí)才返回,沒有則會(huì)阻塞直到超時(shí)返回null
阻塞實(shí)現(xiàn):不用輪詢,當(dāng)隊(duì)列key有數(shù)據(jù)時(shí)候,就會(huì)響應(yīng),這里讀取消息不會(huì)一直循環(huán)去讀取,而是一直阻塞,等到有消息過來才讀取。
該指令還提供了優(yōu)先級(jí)以及超時(shí)參數(shù)
實(shí)現(xiàn)隊(duì)列優(yōu)先級(jí)命令:brpop queue1 queue2 ...
這樣子即可以實(shí)現(xiàn)當(dāng)隊(duì)列1有數(shù)據(jù)時(shí),優(yōu)先處理,比如銀行vip窗口等
實(shí)現(xiàn)超時(shí)退出:redis的brpop默認(rèn)不帶超時(shí)參數(shù)(或者說是默認(rèn)為0(s)),會(huì)一直在進(jìn)程中
實(shí)現(xiàn)命令:brpop queue1 timeout
以下使用方案二實(shí)現(xiàn)思路
例子:發(fā)送平臺(tái)用戶郵箱消息通知(可以多場景、如發(fā)送驗(yàn)證碼、重置密碼等等)
# 第一步 請求發(fā)送的平臺(tái)用戶信息進(jìn)隊(duì)
//...... 獲取用戶信息代碼省略
$userInfo = ['id'=>1, 'name'=>'張三', 'email'=>'393364227@qq.com'];
$redis->lpush('sendEmailQueue', serialize($userInfo)); //serialize 序列化數(shù)組信息,轉(zhuǎn)為字符串
//..... 同步處理,相應(yīng)頁面 發(fā)送成功等信息
# 第二步 在另一個(gè)接口類出隊(duì),并且處理消息
$userInfo = unserialize(brpop('sendEmailQueue'));
//sendEmail 開始發(fā)送郵件操作
# 第三步 將第二步的實(shí)現(xiàn)接口添加到進(jìn)程任務(wù),并且開啟進(jìn)程保護(hù)
//可以使用linux下的Supervisor來做進(jìn)程保護(hù)
//啟動(dòng)隊(duì)列進(jìn)程,即可實(shí)現(xiàn)消息隊(duì)列去發(fā)送郵件了
The End.