Redis實現簡單訊息佇列

人世間發表於2016-01-07

任務非同步化

開啟瀏覽器,輸入地址,按下回車,開啟了頁面。於是一個HTTP請求(request)就由客戶端傳送到伺服器,伺服器處理請求,返回響應(response)內容。

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

更多的時候,伺服器做的額外事情,並不需要客戶端等待,這時候就可以把這些額外的事情非同步去做。從事非同步任務的工具有很多。主要原理還是處理通知訊息,針對通知訊息通常採取是佇列結構。生產和消費訊息進行通訊和業務實現。

生產消費與佇列

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

大概輸出如下:

Redis 佇列

Python內建了一個好用的佇列結構。我們也可以是用redis實現類似的操作。並做一個簡單的非同步任務。

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

生產消費模式

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

釋出訂閱模式

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

Flask 入口

我們分別實現了兩種非同步任務的後端服務,直接啟動他們,就能監聽redis佇列或頻道的訊息了。簡單的測試如下:

啟動指令碼,使用

可以分別在監聽的指令碼輸入中看到非同步訊息。在非同步的任務中,可以執行一些耗時間的操作,當然目前這些做法並不知道非同步的執行結果,如果需要知道非同步的執行結果,可以考慮設計協程任務或者使用一些工具如RQ或者celery等。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

Redis實現簡單訊息佇列 Redis實現簡單訊息佇列

相關文章