您好,登錄后才能下訂單哦!
是一個消息的鏈表,是一個異步處理的數據處理引擎。
PS:可以理解為在redis的list列表中存放消息數據,然后按照排隊方式先進先出(左進右出;右進左出)
主要應用一些延遲或異步操作的場景
比如:發送郵件、發送短信、視頻轉碼、圖片轉碼、日志存儲、導入數據等
在發送郵件或者短信,我們不希望程序一直停留,等待發送成功才相應,而是異步進行處理,即:將待發送的郵件數據添加到消息隊列中,然后按照排隊先后進行異步發送郵件。
不僅能夠提高系統的負荷,還能夠改善因網絡阻塞導致的數據缺失
這個可以理解為:異步處理數據,不會一次性給服務器太多壓力,并且不直接操作數據庫,減少了數據庫的壓力;并且若在網絡阻塞時,若已經添加到消息隊列中,那么這些數據會正常執行,不會造成丟失
整體思路:
前面提到消息隊列,就相當于到銀行窗口排隊,先到的叫號入隊(加入到redis消息隊列),然后排到了則根據相應的叫號出隊。
redis的一些特點:
redis設計用來做緩存的,但是由于它自身的某種特性使得它可以用來做消息隊列,它有幾個阻塞式的API可以使用,正是這些阻塞式的API讓其有能力做消息隊列;另外,做消息隊列的其他特性例如FIFO(先入先出)也很容易實現,只需要一個list對象從頭取數據,從尾部塞數據即可;redis能做消息隊列還得益于其list對象blpop brpop接口以及Pub/Sub(發布/訂閱)的某些接口,它們都是阻塞版的,所以可以用來做消息隊列。
使用redis的lpush/rpop (rpush/lpop) 命令 簡單實現左進右出 或 右進左出 的list列表。
然后需要開啟一個線程任務或者定時任務或者輪詢方式,不停的調用rpop方法查看List中是否有待處理消息。
缺點:每調用一次都會發起一次連接,這會造成不必要的浪費。
1)、如果生產者速度大于消費者消費速度,消息隊列長度會一直增大,時間久了會占用大量內存空間。
2)、如果睡眠時間過長,這樣不能處理一些時效性的消息,睡眠時間過短,也會在連接上造成比較大的開銷。
將方案一中的lpop、rpop命令改為使用blpop(左出)、brpop(右出)
這個指令只有在有元素時才返回,沒有則會阻塞直到超時返回null
阻塞實現:不用輪詢,當隊列key有數據時候,就會響應,這里讀取消息不會一直循環去讀取,而是一直阻塞,等到有消息過來才讀取。
該指令還提供了優先級以及超時參數
實現隊列優先級命令:brpop queue1 queue2 ...
這樣子即可以實現當隊列1有數據時,優先處理,比如銀行vip窗口等
實現超時退出:redis的brpop默認不帶超時參數(或者說是默認為0(s)),會一直在進程中
實現命令:brpop queue1 timeout
以下使用方案二實現思路
例子:發送平臺用戶郵箱消息通知(可以多場景、如發送驗證碼、重置密碼等等)
# 第一步 請求發送的平臺用戶信息進隊
//...... 獲取用戶信息代碼省略
$userInfo = ['id'=>1, 'name'=>'張三', 'email'=>'393364227@qq.com'];
$redis->lpush('sendEmailQueue', serialize($userInfo)); //serialize 序列化數組信息,轉為字符串
//..... 同步處理,相應頁面 發送成功等信息
# 第二步 在另一個接口類出隊,并且處理消息
$userInfo = unserialize(brpop('sendEmailQueue'));
//sendEmail 開始發送郵件操作
# 第三步 將第二步的實現接口添加到進程任務,并且開啟進程保護
//可以使用linux下的Supervisor來做進程保護
//啟動隊列進程,即可實現消息隊列去發送郵件了
The End.
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。