PHP memcache实现消息队列范例
PHP memcache实现消息队列实例
现在memcache在服务器缓存应用比较广泛,下面我来介绍memcache实现消息队列等待的一个例子,有需要了解的朋友可参考。
memche消息队列的原理就是在key上做文章,用以做一个连续的数字加上前缀记录序列化以后消息或者日志。然后通过定时程序将内容落地到文件或者数据库。
php实现消息队列的用处比如在做发送邮件时发送大量邮件很费时间的问题,那么可以采取队列。
方便实现队列的轻量级队列服务器是:
starling支持memcache协议的轻量级持久化服务器
https://github.com/starling/starling
Beanstalkd轻量、高效,支持持久化,每秒可处理3000左右的队列
http://kr.github.com/beanstalkd/
php中也可以使用memcache/memcached来实现消息队列。
<?php /*** Memcache 消息队列类*/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 set( $key, 0, $time );if( !$ret ) return false;$val = 0;}$offset = intval( $offset );if( $offset > 0 ){return $mc->increment( $key, $offset );}elseif( $offset 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 get( $v_key );$mc->delete($v_key);}return $out;}}/**使用方法:QMC::input($key, $value );//写入队列$list = QMC::output($key);//读取队列*/?>
基于PHP共享内存实现的消息队列:
<?php /*** 使用共享内存的PHP循环内存队列实现* 支持多进程, 支持各种数据类型的存储* 注: 完成入队或出队操作,尽快使用unset(), 以释放临界区** @author [email protected]* @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 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; } }

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

许多用户在选择智能手表的时候都会选择的华为的品牌,其中华为GT3pro和GT4都是非常热门的选择,不少用户都很好奇华为GT3pro和GT4有什么区别,下面就就给大家介绍一下二者。华为GT3pro和GT4有什么区别一、外观GT4:46mm和41mm,材质是玻璃表镜+不锈钢机身+高分纤维后壳。GT3pro:46.6mm和42.9mm,材质是蓝宝石玻璃表镜+钛金属机身/陶瓷机身+陶瓷后壳二、健康GT4:采用最新的华为Truseen5.5+算法,结果会更加的精准。GT3pro:多了ECG心电图和血管及安

C语言return的用法有:1、对于返回值类型为void的函数,可以使用return语句来提前结束函数的执行;2、对于返回值类型不为void的函数,return语句的作用是将函数的执行结果返回给调用者;3、提前结束函数的执行,在函数内部,我们可以使用return语句来提前结束函数的执行,即使函数并没有返回值。

function是函数的意思,是一段具有特定功能的可重复使用的代码块,是程序的基本组成单元之一,可以接受输入参数,执行特定的操作,并返回结果,其目的是封装一段可重复使用的代码,提高代码的可重用性和可维护性。

在Web开发中,我们经常需要使用缓存技术来提高网站的性能和响应速度。Memcache是一种流行的缓存技术,它可以缓存任何数据类型、支持高并发和高可用性。本文将介绍如何使用PHP开发中的Memcache,并提供具体代码示例。一、安装Memcache要使用Memcache,我们首先需要在服务器上安装Memcache扩展。在CentOS操作系统中,可以使用以下命令

为什么截图工具在Windows11上不起作用了解问题的根本原因有助于找到正确的解决方案。以下是截图工具可能无法正常工作的主要原因:对焦助手已打开:这可以防止截图工具打开。应用程序损坏:如果截图工具在启动时崩溃,则可能已损坏。过时的图形驱动程序:不兼容的驱动程序可能会干扰截图工具。来自其他应用程序的干扰:其他正在运行的应用程序可能与截图工具冲突。证书已过期:升级过程中的错误可能会导致此issu简单的解决方案这些适合大多数用户,不需要任何特殊的技术知识。1.更新窗口和Microsoft应用商店应用程

第1部分:初始故障排除步骤检查苹果的系统状态:在深入研究复杂的解决方案之前,让我们从基础知识开始。问题可能不在于您的设备;苹果的服务器可能会关闭。访问Apple的系统状态页面,查看AppStore是否正常工作。如果有问题,您所能做的就是等待Apple修复它。检查您的互联网连接:确保您拥有稳定的互联网连接,因为“无法连接到AppStore”问题有时可归因于连接不良。尝试在Wi-Fi和移动数据之间切换或重置网络设置(“常规”>“重置”>“重置网络设置”>设置)。更新您的iOS版本:

在本文中,我们将了解enumerate()函数以及Python中“enumerate()”函数的用途。什么是enumerate()函数?Python的enumerate()函数接受数据集合作为参数并返回一个枚举对象。枚举对象以键值对的形式返回。key是每个item对应的索引,value是items。语法enumerate(iterable,start)参数iterable-传入的数据集合可以作为枚举对象返回,称为iterablestart-顾名思义,枚举对象的起始索引由start定义。如果我们忽

MySQL.proc表的作用和功能详解MySQL是一种流行的关系型数据库管理系统,开发者在使用MySQL时常常会涉及到存储过程(StoredProcedure)的创建和管理。而MySQL.proc表则是一个非常重要的系统表,它存储了数据库中所有的存储过程的相关信息,包括存储过程的名称、定义、参数等。在本文中,我们将详细解释MySQL.proc表的作用和功能
