天天看點

Redis實作簡單消息隊列

打開浏覽器,輸入位址,按下回車,打開了頁面。于是一個​<code>​HTTP​</code>​請求(​<code>​request​</code>​)就由用戶端發送到伺服器,伺服器處理請求,傳回響應(​<code>​response​</code>​)内容。

我們每天都在浏覽網頁,發送大大小小的請求給伺服器。有時候,伺服器接到了請求,會發現他也需要給另外的伺服器發送請求,或者伺服器也需要做另外一些事情,于是最初們發送的請求就被阻塞了,也就是要等待伺服器完成其他的事情。

更多的時候,伺服器做的額外事情,并不需要用戶端等待,這時候就可以把這些額外的事情異步去做。從事異步任務的工具有很多。主要原理還是處理通知消息,針對通知消息通常采取是隊列結構。生産和消費消息進行通信和業務實作。

上述異步任務的實作,可以抽象為生産者消費模型。如同一個餐館,廚師在做飯,吃貨在吃飯。如果廚師做了很多,暫時賣不完,廚師就會休息;如果客戶很多,廚師馬不停蹄的忙碌,客戶則需要慢慢等待。實作生産者和消費者的方式用很多,下面使用​<code>​Python​</code>​标準庫​<code>​Queue​</code>​寫個小例子:

大概輸出如下:

Python内置了一個好用的隊列結構。我們也可以是用redis實作類似的操作。并做一個簡單的異步任務。

Redis提供了兩種方式來作消息隊列。一個是使用​<code>​生産者消費模式​</code>​模式,另外一個方法就是​<code>​釋出訂閱者模式​</code>​。前者會讓一個或者多個用戶端監聽消息隊列,一旦消息到達,消費者馬上消費,誰先搶到算誰的,如果隊列裡沒有消息,則消費者繼續監聽。後者也是一個或多個用戶端訂閱消息頻道,隻要釋出者釋出消息,所有訂閱者都能收到消息,訂閱者都是ping的。

主要使用了redis提供的blpop擷取隊列資料,如果隊列沒有資料則阻塞等待,也就是監聽。

使用redis的pubsub功能,訂閱者訂閱頻道,釋出者釋出消息到頻道了,頻道就是一個消息隊列。

我們分别實作了兩種異步任務的後端服務,直接啟動他們,就能監聽redis隊列或頻道的消息了。簡單的測試如下:

啟動腳本,使用

可以分别在監聽的腳本輸入中看到異步消息。在異步的任務中,可以執行一些耗時間的操作,當然目前這些做法并不知道異步的執行結果,如果需要知道異步的執行結果,可以考慮設計協程任務或者使用一些工具如​<code>​RQ​</code>​或者​<code>​celery​</code>​等。