閱讀987 返回首頁    go 阿裏雲 go 技術社區[雲棲]


[PhalApi實戰篇(1)]Redis隊列處理異步任務

[PhalApi實戰篇(1)]Redis隊列處理異步任務

前言

先在這裏感謝phalapi框架創始人@dogstar,為我們提供了這樣一個優秀的開源框架.

哈嘍大家好呀!之前編寫的PhalApi入門篇和進階篇已經過去了好久了,在此之間也回答了很多小夥伴各種各樣的問題,這裏也希望吧裏麵一些問的比較多的和比較有趣的以及筆者在使用PhalApi一些新的體會,都提取出來為大家帶來一些能夠在實際開發中可以使用的技術或思想,那麼我們就開始我們實戰篇中的第一節 Redis隊列處理異步任務

大家希望喵咪在PhalApi實戰推出一些什麼樣的內容?可以私信我郵箱wenzhenxi@vip.qq.com

附上:

喵了個咪的博客:https://yq.aliyun.com/articles/w-blog.cn

官網地址:https://www.phalapi.net/

開源中國Git地址:https://git.oschina.net/dogstar/PhalApi/tree/release

1.為什麼需要隊列

為什麼需要隊列?其實已經是一個老生常談的一個問題了,隊列有諸多好處比如:

在項目中,將一些無需即時返回且耗時的操作提取出來,進行了異步隊列處理,而這種異步隊列處理的方式大大的節省了服務器的請求響應時間,從而提高了係統的吞吐量。 比較通俗易懂的解釋就是 一個請求處理一些事情 A 業務耗時 30ms B業務 耗時 20ms 然後發郵件 耗時 50ms ,吧其中的發送郵件 寫入隊列 有一個專門負責發送郵件的程序接受這個隊列的消息在吧郵件發送出去,這樣這個請求原來要用100ms現在隻需要50ms , 借助隊列可以吧很多原本很消耗時間的操作單獨有序處理

隊列軟件也很多:RabbitMQ,KafKa這兩款都是非常主流的隊列軟件PhalApi也有提供對應的擴展程序來去使用,但是需要使用它們的成本對相對高一些需要搭建很多複雜的組件,但是相對redis,redis雖然沒有那麼多豐富的功能工具但是它也是隊列軟件中的不二之選

2.理解Redis處理隊列特點

對於PHP來說對Redis支持是特別好的,redis的單線程保障了隊列不會應為並發的問題導致一條消息多人獲取所有也是很適合做為隊列傳輸,PhalApi不僅僅自帶簡單的Redis庫筆者也在它的基礎上封裝了一個更為完善的redis庫,如下:

Redis · 暗夜在火星/PhalApi Library - 碼雲 - 開源中國

隊列主要由兩部分組成一部分是客戶端一部分是消費端,客戶端負責提供消息消費端負責處理隊列這樣的一個形式

在使用redis隊列主要會使用到redis隊列中的List類型,List類型可以從左右兩邊讀取和寫入數據,這樣的形式就可以做到先入先出或者是後入先出這種隊列模式

3.具體實踐(基於PhalApi-Redis擴展)

客戶端的使用比較簡單隻需要初始化Redis鏈接後向左邊寫入數據即可:

客戶端:

//redis鏈接
DI()->redis = new Redis_Lite(DI()->config->get('app.redis.servers'));
//寫入隊列左邊
DI()->redis->set_lPush(隊列鍵名,值, 庫名);

關鍵是消費端的用法,怎麼讓消費端一直不停的處理隊列呢?很多童鞋應該已經想到了利用死循環不停的讀取隊列處理來解決及時處理的問題,但是這樣又會帶來一個新的問題,如果說隊列空了死循環會不會一直高額的消耗CPU資源啊?由於這點就衍生出來兩種具體的用法:

用法一

有的小夥伴就說了,這個還不簡單嗎?當隊列裏麵沒有內容了我就關掉消費端,然後使用crontab過一段時間再啟動進行處理,這就沒有所謂的死循環CPU消耗的問題了,這種解法如下:

while (true) {
    // 讀取隊列右邊
    $msg = DI()->redis->get_rPop(隊列鍵名, 庫名);
  if( !$msg ){
      break;
  }
    // 處理邏輯
  .....
}

然後通過crontab進行定時任務即可

用法二

第二種用法是通過redis隊列的另外一種機製來解決這類問題,相對於get_rPop還有提供一個方法get_brPop,我們可以看一下這個方法的描述**讀取隊列右邊 如果沒有讀取到阻塞一定時間**這個阻塞時間是通過配置文件blocking字段來配置的,使用方式如下

while (true) {
    // 讀取隊列右邊
    $msg = DI()->redis->get_brPop(隊列鍵名, 庫名);
    // 處理邏輯
  .....
}

這種方法相對上麵那種的好處是實時性最好,如果阻塞時間設置的是5秒等待了2秒有消息進來了就裏麵會進入處理模式

上述方式可以使用Supervisor進行常駐內存執行

總結

本次實戰篇為大家講述了怎麼使用Redis來處理隊列來處理異步任務,以及隊列有什麼特點為什麼使用redis隊列,那麼後續的實戰篇也會為大家帶來比較使用的PhalApi各項技術,如果大家有什麼希望喵咪能夠加入到實戰篇的內容可以@我哦!

注:筆者能力有限有說的不對的地方希望大家能夠指出,也希望多多交流!

官網QQ交流群:①群:421032344 ②群:459352221 歡迎大家的加入!

最後更新:2017-05-05 11:01:40

  上一篇:go MaxCompute文章索引(持續更新201705)
  下一篇:go PhalApi-RabbitMQ基於PhalApi專業隊列拓展