redis消息隊列簡單應用

參考 blog.yxccan.cn/blog/detail…

第一次寫掘金博客,小夥伴萌,多多支持喲~(^__^) 嘻嘻php


1、什麼是消息隊列

是一個消息的鏈表,是一個異步處理的數據處理引擎。linux

PS:能夠理解爲在redis的list列表中存放消息數據,而後按照排隊方式先進先出(左進右出;右進左出)redis

2、可使用的應用場景

主要應用一些延遲或異步操做的場景 好比:發送郵件、發送短信、視頻轉碼、圖片轉碼、日誌存儲、導入數據等 在發送郵件或者短信,咱們不但願程序一直停留,等待發送成功才相應,而是異步進行處理,即:將待發送的郵件數據添加到消息隊列中,而後按照排隊前後進行異步發送郵件。數據庫

3、優勢

不只可以提升系統的負荷,還可以改善因網絡阻塞致使的數據缺失 這個能夠理解爲:異步處理數據,不會一次性給服務器太多壓力,而且不直接操做數據庫,減小了數據庫的壓力;而且若在網絡阻塞時,若已經添加到消息隊列中,那麼這些數據會正常執行,不會形成丟失數組

4、redis實現隊列方案

總體思路: 前面提到消息隊列,就至關於到銀行窗口排隊,先到的叫號入隊(加入到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異步

5、代碼實現思路

如下使用方案二實現思路 例子:發送平臺用戶郵箱消息通知(能夠多場景、如發送驗證碼、重置密碼等等)spa

# 第一步 請求發送的平臺用戶信息進隊

//...... 獲取用戶信息代碼省略
$userInfo = ['id'=>1, 'name'=>'張三', 'email'=>'393364227@qq.com'];
$redis->lpush('sendEmailQueue', serialize($userInfo)); //serialize 序列化數組信息,轉爲字符串
//..... 同步處理,相應頁面 發送成功等信息


# 第二步 在另外一個接口類出隊,而且處理消息

$userInfo = unserialize(brpop('sendEmailQueue'));
//sendEmail 開始發送郵件操做

# 第三步 將第二步的實現接口添加到進程任務,而且開啓進程保護
//可使用linux下的Supervisor來作進程保護
//啓動隊列進程,便可實現消息隊列去發送郵件了

複製代碼

The End.

相關文章
相關標籤/搜索