1. 程式人生 > 其它 >[PhalApi實戰篇(1)]Redis佇列處理非同步任務

[PhalApi實戰篇(1)]Redis佇列處理非同步任務

[PhalApi實戰篇(1)]Redis佇列處理非同步任務

前言

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

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

大家希望喵咪在PhalApi實戰推出一些什麼樣的內容?可以私信我郵箱[email protected]

附上:

喵了個咪的部落格:w-blog.cn

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

開源中國Git地址:http://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 歡迎大家的加入!