用redis和php實現簡單的訊息佇列伺服器

2021-10-01 08:08:05 字數 3253 閱讀 5781

redis擁有五大基本的資料結構:string(字串)、list(列表)、hash(雜湊)、sets(集合)、sorted sets(有序集合)。列表結構類似於線性表裡的雙向鍊錶,雙向鍊錶的特點是既可以從表頭順序遍歷鍊錶,也可以從表尾開始順序遍歷鍊錶。雙向煉表示意圖:

利用list資料結構,我們可以實現簡單的訊息佇列。redis提供了很多操作list的api,這裡以php的redis擴充套件包裝的redis  api為例,簡單介紹下主要的操作方法,詳細的引數及使用方法參考官方文件。

阻塞版的lpop方法。

阻塞版的rpoplpush方法

返回按順序索引的特定序號的元素

在元素的前面或後面插入值

返回並移除列表的第乙個元素

在列表的頭部新增乙個字串值,若列表不存在,則建立列表後再新增。

如果列表存在,則在列表的頭部新增乙個字串值

返回列表中特定範圍的值

將列表中重複出現的某個值,按列表順序刪除指定個數

設定某個索引處的值為特定值

移除列表中的某個範圍值

返回並刪除列表最後乙個值

移除第乙個列表的尾部元素,然後壓入第二個列表的頭部,且返回這個元素的值

在列表的尾部新增乙個字串值,若列表不存在,則建立列表後再新增。

如果列表存在,則在列表的尾部新增乙個字串值

返回列表的長度

需要注意的一點是,redis的列表結構只能儲存字串值。我們可以用redis的list資料結構來實現訊息佇列,具體點就是用redis的list結構來儲存生產者產生的訊息,此外,我們還需要乙個生產者來生產訊息,和乙個消費者來消費或者說處理訊息。php的redis擴充套件提供了很好的操作redis的介面,因此可以用php來實現生產者和消費者。首先新建乙個messageproducer.php檔案,裡面有我們要的生產者類messageproducer:

<?php 

/** * 訊息生產者

* *@author ldy

*/class messageproducer

if(isset($config['db']) && !empty($config['db']))

} /**

*發布一條訊息到指定佇列

* *@param string $queuename 佇列名稱

*@param string $message 訊息

*@param int $expireat 過期時間,unix秒級時間戳

* *@return true|throw exception

* */

public function publish($queuename, $message, $expireat=null)

catch (\redi***ception $e) catch (\errorexception $e)

}}

然後再建立乙個消費者類處理訊息:

<?php 

/** *消費者

* *@author ldy

*/class messageconsumer

/***設定佇列名稱

*@param string $queuename

*/ public function setqueuename($queuename)

/***設定訊息處理器

*@param object|\closure $handler

*/ public function sethandler($handler)

/***連線redis伺服器

* *@param array $config redis連線配置

*/ public function connect($config)

if(isset($config['db']) && !empty($config['db']))

} /*處理訊息*/

public function consume()

elseif(is_object($this->handler))else

} /*執行訊息消費者*/

public function run() }

}

建立乙個指令碼publish.php產生訊息,這個指令碼呼叫了上面的生產者類:

#!/usr/bin/php

<?php

require './messageproducer.php';

$producer = new messageproducer();

$producer->connect([

'host' => '127.0.0.1',

'port' => 6379,

]);$producer->publish('my-queue', 'you sad hello world!');

最後再建立乙個testconsumer.php檔案測試消費者是否正常工作:

#!/usr/bin/php

<?php

require './messageconsumer.php';

//建立乙個閉包來處理訊息

$handler = function($message);

$consumer = new messageconsumer('my-queue', $handler);

$consumer->connect([

'host' => '127.0.0.1',

'port' => 6379,

]);$consumer->run();

在linux命令列執行testconsumer.php檔案:

root@vagrant-ubuntu-trusty-64:/vagrant/php# php   testconsumer.php

這樣php指令碼程式就開始監聽佇列訊息了。執行php publish.php指令碼生產訊息,測試訊息是否被消費者接收到:

訊息被成功接收到。這樣乙個簡單的訊息佇列伺服器就實現了。在生產環境我們可能希望消費者程式成為乙個常駐程序,這樣就不用每次都要在命令列執行testconsumer.php指令碼開啟。這裡推薦用supervisor程序管理器實現,詳情可以檢視官網,這裡不做詳細介紹。

PHP例項 用PHP簡單實現多條件查詢

在我們的 設計過程中,經常會用到多條件查詢,本文的原始碼是乙個二手房屋查詢的例子。在本例中,我們要實現能夠通過地理位置,物業型別,房屋 房屋面積及資訊發布日期等多個條件查詢到客戶所需的資料。查詢檔案 search.php 一 生成查詢語句 12 conn mysql connect localhos...

用php列印出日曆 PHP實現簡單的日曆程式

說到對日期和時間的處理,就一定要介紹一下日曆程式的編寫,大多數讀者可能都會認為日曆的作用只是為了在頁面上顯示當前的日期,其實不然,日曆在我們的開發中有著更重要的作用。例如,我們開發乙個 記事本 就需要通過日曆設定日期,另外在一些系統中需要按日期去安排任務也需要用到日曆等等。本節的示例中涉及的日期和時...

用redis實現秒殺

今日在研究秒殺系統,用資料庫的樂觀鎖可以實現,但是在高併發下可能並不好,所以就想到了快取系統redis,因為redis本身也有鎖機制,廢話不多說,直接上 請大神指點不足的地方。class a public class myrunnable implements runnable override p...