亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

PHP+memcache實現消息隊列案例分享

2020-03-22 20:22:51
字體:
來源:轉載
供稿:網友
memche消息隊列的原理就是在key上做文章,用以做一個連續的數字加上前綴記錄序列化以后消息或者日志。然后通過定時程序將內容落地到文件或者數據庫。php實現消息隊列的用處比如在做發送郵件時發送大量郵件很費時間的問題,那么可以采取隊列。
方便實現隊列的輕量級隊列服務器是:
starling支持memcache協議的輕量級持久化服務器
https://github.com/starling/starling
Beanstalkd輕量、高效,支持持久化,每秒可處理3000左右的隊列
http://kr.github.com/beanstalkd/
php中也可以使用memcache/memcached來實現消息隊列。復制代碼 代碼如下:
?php
/**
* Memcache 消息隊列類
*/
html' target='_blank'>class QMC {
const PREFIX = 'ASDFASDFFWQKE';
/**
* 初始化mc
* @staticvar string $mc
* @return Memcache
*/
static private function mc_init() {
static $mc = null;
if (is_null($mc)) {
$mc = new Memcache;
$mc- connect('127.0.0.1', 11211);
}
return $mc;
}
/**
* mc 計數器,增加計數并返回新的計數
* @param string $key 計數器
* @param int $offset 計數增量,可為負數.0為不改變計數
* @param int $time 時間
* @return int/false 失敗是返回false,成功時返回更新計數器后的計數
*/
static public function set_counter( $key, $offset, $time=0 ){
$mc = self::mc_init();
$val = $mc- get($key);
if( !is_numeric($val) || $val 0 ){
$ret = $mc- set( $key, 0, $time );
if( !$ret ) return false;
$val = 0;
}
$offset = intval( $offset );
if( $offset 0 ){
return $mc- increment( $key, $offset );
}elseif( $offset 0 ){
return $mc- decrement( $key, -$offset );
}
return $val;
}
/**
* 寫入隊列
* @param string $key
* @param mixed $value
* @return bool
*/
static public function input( $key, $value ){
$mc = self::mc_init();
$w_key = self::PREFIX.$key.'W';
$v_key = self::PREFIX.$key.self::set_counter($w_key, 1);
return $mc- set( $v_key, $value );
}
/**
* 讀取隊列里的數據
* @param string $key
* @param int $max 最多讀取條數
* @return array
*/
static public function output( $key, $max=100 ){
$out = array();
$mc = self::mc_init();
$r_key = self::PREFIX.$key.'R';
$w_key = self::PREFIX.$key.'W';
$r_p = self::set_counter( $r_key, 0 );//讀指針
$w_p = self::set_counter( $w_key, 0 );//寫指針
if( $r_p == 0 ) $r_p = 1;
while( $w_p = $r_p ){
if( --$max 0 ) break;
$v_key = self::PREFIX.$key.$r_p;
$r_p = self::set_counter( $r_key, 1 );
$out[] = $mc- get( $v_key );
$mc- delete($v_key);
}
return $out;
}
}
/**
使用方法:
QMC::input($key, $value );//寫入隊列
$list = QMC::output($key);//讀取隊列
*/
?
基于PHP共享內存實現的消息隊列:復制代碼 代碼如下:
?php
/**
* 使用共享內存的PHP循環內存隊列實現
* 支持多進程, 支持各種數據類型的存儲
* 注: 完成入隊或出隊操作,盡快使用unset(), 以釋放臨界區
*
* @author wangbinandi@gmail.com
* @created 2009-12-23
*/
class ShmQueue
{
private $maxQSize = 0; // 隊列最大長度
private $front = 0; // 隊頭指針
private $rear = 0; // 隊尾指針
private $blockSize = 256; // 塊的大小(byte)
private $memSize = 25600; // 最大共享內存(byte)
private $shmId = 0;
private $filePtr = './shmq.ptr';
private $semId = 0;
public function __construct()
{
$shmkey = ftok(__FILE__, 't');
$this- shmId = shmop_open($shmkey, "c", 0644, $this- memSize );
$this- maxQSize = $this- memSize / $this- blockSize;
// 申?一個信號量
$this- semId = sem_get($shmkey, 1);
sem_acquire($this- semId); // 申請進入臨界區
$this- init();
}
private function init()
{
if ( file_exists($this- filePtr) ){
$contents = file_get_contents($this- filePtr);
$data = explode( '|', $contents );
if ( isset($data[0]) && isset($data[1])){
$this- front = (int)$data[0];
$this- rear = (int)$data[1];
}
}
}
public function getLength()
{
return (($this- rear - $this- front + $this- memSize) % ($this- memSize) )/$this- blockSize;
}
public function enQueue( $value )
{
if ( $this- ptrInc($this- rear) == $this- front ){ // 隊滿
return false;
}
$data = $this- encode($value);
shmop_write($this- shmId, $data, $this- rear );
$this- rear = $this- ptrInc($this- rear);
return true;
}
public function deQueue()
{
if ( $this- front == $this- rear ){ // 隊空
return false;
}
$value = shmop_read($this- shmId, $this- front, $this- blockSize-1);
$this- front = $this- ptrInc($this- front);
return $this- decode($value);
}
private function ptrInc( $ptr )
{
return ($ptr + $this- blockSize) % ($this- memSize);
}
private function encode( $value )
{
$data = serialize($value) . "__eof";
echo '';
echo strlen($data);
echo '';
echo $this- blockSize -1;
echo '';
if ( strlen($data) $this- blockSize -1 ){
throw new Exception(strlen($data)." is overload block size!");
}
return $data;
}
private function decode( $value )
{
$data = explode("__eof", $value);
return unserialize($data[0]);
}
public function __destruct()
{
$data = $this- front . '|' . $this- rear;
file_put_contents($this- filePtr, $data);
sem_release($this- semId); // 出臨界區, 釋放信號量
}
}
/*
// 進隊操作
$shmq = new ShmQueue();
$data = 'test data';
$shmq- enQueue($data);
unset($shmq);
// 出隊操作
$shmq = new ShmQueue();
$data = $shmq- deQueue();
unset($shmq);
*/
?
對于一個很大的消息隊列,頻繁進行進行大數據庫的序列化 和 反序列化,有太耗費。下面是我用PHP 實現的一個消息隊列,只需要在尾部插入一個數據,就操作尾部,不用操作整個消息隊列進行讀取,與操作。但是,這個消息隊列不是線程安全的,我只是盡量的避免了沖突的可能性。如果消息不是非常的密集,比如幾秒鐘才一個,還是可以考慮這樣使用的。
如果你要實現線程安全的,一個建議是通過文件進行鎖定,然后進行操作。下面是代碼:
代碼如下:復制代碼 代碼如下:
class Memcache_Queue
{
private $memcache;
private $name;
private $prefix;
function __construct($maxSize, $name, $memcache, $prefix = "__memcache_queue__")
{
if ($memcache == null) {
throw new Exception("memcache object is null, new the object first.");
}
$this- memcache = $memcache;
$this- name = $name;
$this- prefix = $prefix;
$this- maxSize = $maxSize;
$this- front = 0;
$this- real = 0;
$this- size = 0;
}
function __get($name)
{
return $this- get($name);
}
function __set($name, $value)
{
$this- add($name, $value);
return $this;
}
function isEmpty()
{
return $this- size == 0;
}
function isFull()
{
return $this- size == $this- maxSize;
}
function enQueue($data)
{
if ($this- isFull()) {
throw new Exception("Queue is Full");
}
$this- increment("size");
$this- set($this- real, $data);
$this- set("real", ($this- real + 1) % $this- maxSize);
return $this;
}
function deQueue()
{
if ($this- isEmpty()) {
throw new Exception("Queue is Empty");
}
$this- decrement("size");
$this- delete($this- front);
$this- set("front", ($this- front + 1) % $this- maxSize);
return $this;
}
function getTop()
{
return $this- get($this- front);
}
function getAll()
{
return $this- getPage();
}
function getPage($offset = 0, $limit = 0)
{
if ($this- isEmpty() || $this- size $offset) {
return null;
}
$keys[] = $this- getKeyByPos(($this- front + $offset) % $this- maxSize);
$num = 1;
for ($pos = ($this- front + $offset + 1) % $this- maxSize; $pos != $this- real; $pos = ($pos + 1) % $this- maxSize)
{
$keys[] = $this- getKeyByPos($pos);
$num++;
if ($limit 0 && $limit == $num) {
break;
}
}
return array_values($this- memcache- get($keys));
}
function makeEmpty()
{
$keys = $this- getAllKeys();
foreach ($keys as $value) {
$this- delete($value);
}
$this- delete("real");
$this- delete("front");
$this- delete("size");
$this- delete("maxSize");
}
private function getAllKeys()
{
if ($this- isEmpty())
{
return array();
}
$keys[] = $this- getKeyByPos($this- front);
for ($pos = ($this- front + 1) % $this- maxSize; $pos != $this- real; $pos = ($pos + 1) % $this- maxSize)
{
$keys[] = $this- getKeyByPos($pos);
}
return $keys;
}
private function add($pos, $data)
{
$this- memcache- add($this- getKeyByPos($pos), $data);
return $this;
}
private function increment($pos)
{
return $this- memcache- increment($this- getKeyByPos($pos));
}
private function decrement($pos)
{
$this- memcache- decrement($this- getKeyByPos($pos));
}
private function set($pos, $data)
{
$this- memcache- set($this- getKeyByPos($pos), $data);
return $this;
}
private function get($pos)
{
return $this- memcache- get($this- getKeyByPos($pos));
}
private function delete($pos)
{
return $this- memcache- delete($this- getKeyByPos($pos));
}
private function getKeyByPos($pos)
{
return $this- prefix . $this- name . $pos;
}
}
PHP教程

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国产区一区二区三区在线观看| 日韩欧美极品在线观看| 国产亚洲xxx| 亚洲自拍偷拍视频| 国产欧美最新羞羞视频在线观看| 色偷偷av一区二区三区| 日韩视频第一页| 欧美大片欧美激情性色a∨久久| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲欧洲在线播放| 久久这里有精品| 亚洲精品在线视频| 亚洲丝袜一区在线| 26uuu久久噜噜噜噜| 国产99在线|中文| 久久天堂av综合合色| 久久久国产精品一区| 国产香蕉一区二区三区在线视频| 国产欧美在线视频| 97av在线视频免费播放| 国产精品高精视频免费| 国产午夜精品免费一区二区三区| 日本午夜精品理论片a级appf发布| 日韩国产高清污视频在线观看| 欧美午夜久久久| www.欧美精品| 日韩成人中文字幕| 欧美成人黄色小视频| 亚洲性无码av在线| x99av成人免费| 亚洲伊人久久大香线蕉av| 欧美日韩免费看| 成人免费福利视频| 亚洲精品天天看| 久久精品成人一区二区三区| 亚洲综合精品伊人久久| 神马国产精品影院av| 伊是香蕉大人久久| 亚洲第一精品夜夜躁人人躁| 国内精品久久久久久| 国产日韩欧美中文| 日韩精品免费一线在线观看| 日韩女在线观看| 国产日韩欧美黄色| 亚洲精品视频在线观看视频| 亚洲人成电影网站| 夜色77av精品影院| 992tv成人免费视频| 日韩黄色在线免费观看| 亚洲曰本av电影| 久久99亚洲热视| 亚洲欧美中文日韩在线v日本| 国产精品久久久久久久7电影| 亚洲在线观看视频网站| 亚洲精品国产福利| 热久久免费视频精品| 一区二区中文字幕| 久久精品电影网| 国内精品视频一区| 亚洲精品av在线| 在线免费观看羞羞视频一区二区| 亚洲最新视频在线| 久久久噜噜噜久久| 日韩在线中文字| 国产97免费视| 成人啪啪免费看| 色天天综合狠狠色| 97免费中文视频在线观看| 国产视频观看一区| 91国产中文字幕| 亚洲理论在线a中文字幕| 久久夜色精品国产欧美乱| 亚洲欧美国产va在线影院| 4k岛国日韩精品**专区| 韩日欧美一区二区| 九九久久综合网站| 久久精品亚洲精品| 久久精品中文字幕电影| 97色在线视频| 国产成人精品在线| 欧美午夜视频一区二区| 亚洲欧美日本另类| 亚洲乱码av中文一区二区| 亚洲综合视频1区| www.亚洲男人天堂| 亚洲一区二区久久| 成人激情黄色网| 久久欧美在线电影| 亚洲精品www| 久久久电影免费观看完整版| www.美女亚洲精品| 欧美亚洲免费电影| 91干在线观看| 欧美性xxxx极品hd满灌| 2020久久国产精品| 韩国美女主播一区| 一区二区日韩精品| 欧美一区第一页| 国模极品一区二区三区| 欧美日韩国产综合新一区| 亲爱的老师9免费观看全集电视剧| 亚洲美女在线视频| 欧美日韩美女视频| 亚洲午夜国产成人av电影男同| 久久久www成人免费精品| 国产精品99久久久久久www| 欧美在线观看视频| 国产精品网址在线| 亚洲高清在线观看| 欧美成年人视频网站欧美| 久久频这里精品99香蕉| 欧美黄色www| 91社影院在线观看| 欧美国产第二页| 亚洲国产精品人久久电影| 最近2019年手机中文字幕| 欧美不卡视频一区发布| 精品无人区乱码1区2区3区在线| 国产精品电影网站| 欧美理论电影在线观看| 欧美色道久久88综合亚洲精品| 91精品综合视频| 亚洲第一精品自拍| 国产成人精品日本亚洲专区61| 日韩二区三区在线| 午夜精品久久久久久久99热浪潮| 日本欧美国产在线| 欧美激情影音先锋| 欧美日韩国产中文精品字幕自在自线| 亚洲女人天堂成人av在线| 日本亚洲精品在线观看| 欧美中文字幕视频在线观看| 中日韩美女免费视频网址在线观看| 日本久久91av| 综合国产在线观看| 欧美亚洲视频在线观看| 亚洲欧洲日韩国产| 日韩av中文字幕在线免费观看| 久久精品色欧美aⅴ一区二区| 国产精品一区二区久久久| 亚洲乱码一区av黑人高潮| 国产亚洲精品久久久久久777| 成人精品视频久久久久| 欧美三级免费观看| 国产精品成久久久久三级| 成人黄色影片在线| 久久久久久国产精品三级玉女聊斋| 成人国产精品一区二区| 国产精品91视频| 国产精品久久av| 国产日韩欧美成人| 久久亚洲精品一区| 国产精品一区二区三区久久| 精品国产区一区二区三区在线观看| 日韩av免费在线看| 成年无码av片在线| 亚洲精品网址在线观看| 不卡在线观看电视剧完整版| 欧美成人精品三级在线观看| 欧美午夜无遮挡| 国产精品极品尤物在线观看| 国产精品国产三级国产aⅴ9色| 亚洲香蕉成视频在线观看| 国产日韩精品在线观看|