PHP memcache实现消息队列实例

合集下载

消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例

消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例

msgsnd()为阻塞函数,当消息队列容量满或消息个数满会阻塞。

消息队列已被删除,则返回EIDRM错误;被信号中断返回E_INTR错误。

如果设置IPC_NOWAIT消息队列满或个数满时会返回-1,并且置EAGAIN错误。

msgrcv()解除阻塞的条件有以下三个:①消息队列中有了满足条件的消息。

②msqid代表的消息队列被删除。

③调用msgrcv()的进程被信号中断。

消息队列使用程序范例5. 消息队列控制范例msgctl.c源代码如下:#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/ipc.h>#include <sys/msg.h>#include <error.h>#define TEXT_SIZE 512struct msgbuf{long mtype ;char mtext[TEXT_SIZE] ;} ;int main(int argc, char **argv){int msqid ;struct msqid_ds info ;struct msgbuf buf ;struct msgbuf buf1 ;int flag ;int sendlength, recvlength ;msqid = msgget( IPC_PRIVATE, 0666 ) ;if ( msqid < 0 ){perror("get ipc_id error") ;return -1 ;}buf.mtype = 1 ;strcpy(buf.mtext, "happy new year!") ; sendlength = sizeof(struct msgbuf) - sizeof(long) ; flag = msgsnd( msqid, &buf, sendlength , 0 ) ;if ( flag < 0 ){perror("send message error") ;return -1 ;}buf.mtype = 3 ;strcpy(buf.mtext, "good bye!") ;sendlength = sizeof(struct msgbuf) - sizeof(long) ; flag = msgsnd( msqid, &buf, sendlength , 0 ) ;if ( flag < 0 ){perror("send message error") ;return -1 ;}flag = msgctl( msqid, IPC_STAT, &info ) ;if ( flag < 0 ){perror("get message status error") ;return -1 ;}printf("uid:%d, gid = %d, cuid = %d, cgid= %d\n" ,info.msg_perm.uid, info.msg_perm.gid, info.msg_perm.cuid, info.msg_perm.cgid ) ;printf("read-write:%03o, cbytes = %lu, qnum = %lu,qbytes= %lu\n" ,info.msg_perm.mode&0777, info.msg_cbytes, info.msg_qnum, info.msg_qbytes ) ;system("ipcs -q") ;recvlength = sizeof(struct msgbuf) - sizeof(long) ;memset(&buf1, 0x00, sizeof(struct msgbuf)) ;flag = msgrcv( msqid, &buf1, recvlength ,3,0 ) ;if ( flag < 0 ){perror("recv message error") ;return -1 ;}printf("type=%d, message=%s\n", buf1.mtype, buf1.mtext) ;flag = msgctl( msqid, IPC_RMID,NULL) ;if ( flag < 0 ){perror("rm message queue error") ;return -1 ;}system("ipcs -q") ;return 0 ;}编译gcc msgctl.c –o msgctl。

thinkphp实现redis简单的消息队列

thinkphp实现redis简单的消息队列

thinkphp实现redis简单的消息队列thinkphp 实现redis简单的消息队列本章简单的实现。

消息队列的⼊列和出列1.⼊列,⼊列作为⽣产者,只管尽情的成产即可,⽆需考虑其他(秒杀、抢购场景除外)。

此次我们假如有⼗个⽤户进⼊队列。

//⼊列,⽣产者public function into(){$redis = new Redis();//业务场景不在此阐述for ( $i = 1 ; $i <= 10 ; $i++ ){$user = array('user_id'=>$i,'username'=>'demo'.$i);$redis->lPush('data',json_encode($user));}}2.查看队列中的所有数据//查看所有数据public function data(){$redis = new Redis();dump($redis->lRange('data',0,-1));}结果array(10) {[0] => string(34) "{"user_id":10,"username":"demo10"}"[1] => string(32) "{"user_id":9,"username":"demo9"}"[2] => string(32) "{"user_id":8,"username":"demo8"}"[3] => string(32) "{"user_id":7,"username":"demo7"}"[4] => string(32) "{"user_id":6,"username":"demo6"}"[5] => string(32) "{"user_id":5,"username":"demo5"}"[6] => string(32) "{"user_id":4,"username":"demo4"}"[7] => string(32) "{"user_id":3,"username":"demo3"}"[8] => string(32) "{"user_id":2,"username":"demo2"}"[9] => string(32) "{"user_id":1,"username":"demo1"}"}3.出列,出列为消费者,同样,尽管尽情的消费即可,只要队列有数据就进⾏消费,勤勤恳恳的⼯作。

php运用memcache的完整实例

php运用memcache的完整实例

php运⽤memcache的完整实例前⾔memcache实际上也是⼀个服务器,不过他是存在内存⾥⾯的不是存在磁盘⾥⾯的优点速度很快缺点不能永久存储,存放⼤⼩受内存限制没有⽤户名跟防⽕墙,mysql有不过缓存⾥⾯也不会存储重要信息什么的,速度快就很ok,不过受内存限制有点伤,毕竟内存条⽐较贵memcache如何安装以window举例,将.exe⽂件放在c盘下,ctrl+r 打开运⾏,cmd进⼊dos,找到memcache的根⽬录下运⾏指令memcached.exe -d install 进⾏安装卸载就是uninstall如果安装成功运⾏指令memcached -h 查看⼀下启动memcache 运⾏指令memcached.exe -d start 停⽌就是stop去任务管理器看⼀下启动了没有,基本没有啥踩雷的地⽅。

启动好之后,咱们就可以运⾏memcache了。

memcache的默认端⼝号是11211,如果你想更改端⼝号让别⼈查不到的话,需要去注册表regedit找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached Server将这个值改为"c:\memcached\memcached.exe" -p 20000 -d runservice 即可,这样的话访问得按照20000的端⼝访问了然后我这⾥⽤的telnet来操作(也可以下载secureCRT来弄)运⾏指令: telnet 127.0.0.1 11211(如果改端⼝号了,这⾥同步)先打⼏个空格再说在memcache服务器⾥⾯的操作暂时不说了,主要说下在php⾥⾯的操作(今天他不是主⾓),将php_memcache.dll放在php.ini下,可以ctrl+f寻找extension,然后在最后加上 * extension=php_memcache.dll*然后 phpinfo查看⼀下有没有问题$me = new Memcache();var_dump($me);这样就说明创建了memcache缓存对象了当我们客户端访问服务器的时候,如果每⼀次都从数据库读取数据的话,如果访问量⽐较⼤的话,就卡的很,主要是如果优化⽐较费钱,这种针对长期或者⼀段时间不会更改的⽹页的内容,如果是实时的话例如秒杀什么的需要⾼并发或者是页⾯⼀直在更新,还是不能⽤缓存机制的好。

phpmemcached的实例用法详解

phpmemcached的实例用法详解

phpmemcached的实例⽤法详解1、启动Memcached。

2、使⽤ps命令查看⼀下运⾏状态。

3、创建⼀个Memcached对象。

4、通过add和get⽅法添加数据即可。

记得⼀定要先启动Memcached哦![root@localhost ~]# /usr/bin/memcached -d -l 127.0.0.1 -p 11211 -m 150 -u root-d 守护进程模式(退出终端窗⼝之后使程序还在运⾏),-l 指定IP地址127.0.0.1 ,-p 指定端⼝号11211,-m 为memcached分配多少内存(单位:M),-u 指定使⽤哪个⽤户启动memcached使⽤ps命令查看⼀下运⾏状态:[root@localhost ~]# ps -ef | grep memcached知识点扩充:⼀、memcached 简介memcached是⾼性能的分布式内存缓存服务器。

⼀般的使⽤⽬的是,通过缓存数据库查询结果,减少数据库访问次数,以提⾼动态Web应⽤的速度、提⾼可扩展性。

它可以应对任意多个连接,使⽤⾮阻塞的⽹络IO。

由于它的⼯作机制是在内存中开辟⼀块空间,然后建⽴⼀个HashTable,Memcached⾃管理这些HashTable。

⼆、memcached 安装⾸先是下载 memcached 了,⽬前最新版本是 1.1.12,直接从官⽅⽹站即可下载到 memcached-1.1.12.tar.gz。

除此之外,memcached ⽤到了 libevent,我下载的是 libevent-1.1a.tar.gz。

接下来是分别将 libevent-1.1a.tar.gz 和 memcached-1.1.12.tar.gz 解开包、编译、安装:# tar -xzf libevent-1.1a.tar.gz # cd libevent-1.1a# ./configure --prefix=/usr# make# make install# cd .. # tar -xzfmemcached-1.1.12.tar.gz# cd memcached-1.1.12 # ./configure --prefix=/usr# make# make install安装完成之后,memcached 应该在 /usr/bin/memcached。

php的Memcache方法介绍及应用实例

php的Memcache方法介绍及应用实例

使用Memcache在PHP中调试方法的介绍及应用如果我们在网络开发中,特别是大访问量的web项目开发中,为了提高响应速度,减少数据查询运算,那么我们都会选用memcahce。

首先我们必须要安装,接下来如何使用memcache,在这里介绍下在linux下安装和windows下安装如下及配置:一、linux下的Memcache安装:1.下载memcache的linux版本,注意memcached 用libevent 来作事件驱动,所以要先安装有libevent。

2. 安装pecl::memcache。

用pecl 命令行工具安装:pecl install memcache或直接从源码安装:phpize./configuremakemake install二、Windows下的Memcache安装:1. 下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached2. 在终端(也即cmd命令界面)下输入‘c:\memcached\memcached.exe -d install’安装3. 再输入:‘c:\memcached\memcached.exe -d start’启动。

NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。

这样服务器端已经安装完毕了。

4.下载/ext.php/php_memcache.dll,请自己查找对应的php版本的文件5. 在C:\winnt\php.ini 加入一行‘extension=php_memcache.dll’6.重新启动Apache,然后查看一下phpinfo,如果有memcache,那么就说明安装成功!三、memcached的基本设置:-p 监听的端口-l 连接的IP地址, 默认是本机-d start 启动memcached服务-d restart 重起memcached服务-d stop|shutdown 关闭正在运行的memcached服务-d install 安装memcached服务-d uninstall 卸载memcached服务-u 以的身份运行(仅在以root运行的时候有效)-m 最大内存使用,单位MB。

PHP数据库操作二:memcache用法分析

PHP数据库操作二:memcache用法分析

PHP数据库操作⼆:memcache⽤法分析本⽂实例讲述了PHP数据库操作之memcache⽤法。

分享给⼤家供⼤家参考,具体如下:在⼀个⾼并发的web应⽤中,数据库存取瓶颈⼀直是个⼤问题,⼀旦达到某个极限,数据库很容易崩溃,但是如果我们把常⽤的数据放到内存中,在需要的时候从内存中取,不光读取速度快,⽽且节约数据库IO。

memcache简介Memcache是⼀个⾼性能的分布式的内存对象缓存系统,通过在内存⾥维护⼀个统⼀的巨⼤的hash表,它能够⽤来存储各种格式的数据,包括图像、视频、⽂件以及数据库检索的结果等。

简单的说就是将数据调⽤到内存中,然后从内存中读取,从⽽⼤⼤提⾼读取速度。

memcache的mem是内存(memory),cache是缓存,结合是内存缓存的意思。

我们应⽤memcache时,读取数据先从memcache 内读取,若查找不到再去数据库⾥查找,并将数据存⼊memcache,待下次查找时便能轻易找到。

需要注意:memcache是内存型的数据库,因为内存的关闭释放的特性,memcache也⽆法持久化存储内容; memcache内部是分块存储,所以⼤于1M的数据也⽆法存储。

memcache依赖libevent库,安装前需确认已经安装了libevent库。

memcache是⼀个轻量级的内存型数据库,只⽀持key-value型的存储。

memcache中没有关于⽤户,密码的设置,所以在配置时要配置防⽕墙的端⼝限制连接,以达到安全的⽬的。

使⽤repcached也能轻易实现memcache的单master单slave主从复制。

memcache的应⽤场景存储⼤量不需要持久存储或数据库内已存在不会变动的数据。

读取数据⾮常频繁数据,要求⼩于1M。

数据类型简单的key-value型数据。

计算好的结果和渲染后的⽹页模板⽂件。

因其原⼦递增性,可以⽤来计数。

因为可以设置数据过期时间的特性,存储期限数据。

不过需要注意,memcache会在分配的内存不⾜时以最近最少使⽤原则(LRU)重⽤内存,可能会导致信息提前被删除。

PHP教程:php操作memcached方法实例

PHP教程:php操作memcached方法实例

PHP教程:php操作memcached⽅法实例1⾸先建⽴Clsss类⽂件memcached.class.php<?phpclass Memcacheds{//声明静态成员变量 private static $m = null;private static $cache = null;public function __construct() {self::$m = new Memcached();self::$m->addServer('127.0.0.1','11211'); //写⼊缓存地址,port }//为当前类创建对象 private static function Men(){self::$cache = new Memcacheds();return self::$m;}/** 加⼊缓存数据* @param string $key 获取数据唯⼀key* @param String||Array $value 缓存数据* @param $time memcache⽣存周期(秒)*/ public static function setMen($key,$value,$time){self::Men()->set($key,$value,$time);}/** 获取缓存数据* @param string $key* @return */ public static function getMen($key){return self::Men()->get($key);}/** 删除相应缓存数据* @param string $key* @return */ public static function delMen($key){self::Men()->delete($key);}/** 删除全部缓存数据*/ public static function delAllMen(){self::Men()->flush();}/** 删除全部缓存数据*/ public static function menStatus(){return self::Men()->getStats();}}?>2使⽤⽅法实例//引⼊类⽂件require dirname(__FILE__).'/memcached.class.php'; function Get_memcached($str,$key,$time){$key = md5($key);Memcacheds::setMen($key,$str,$time); //写⼊缓存$get = Memcacheds::getMen($key); //读取缓存return $get;}echo function Get_memcached('data','key',3600);希望本⽂所述对⼤家的php程序设计有所帮助。

Memcache所有方法及参数详解

Memcache所有方法及参数详解

Memcache所有⽅法及参数详解memcache函数所有的⽅法列表如下:参考/manual/zh/function.Memcache-add.phpMemcache::add - 添加⼀个值,如果已经存在,则返回falseMemcache::addServer - 添加⼀个可供使⽤的服务器地址Memcache::close - 关闭⼀个Memcache对象Memcache::connect - 创建⼀个Memcache对象memcache_debug - 控制调试功能Memcache::decrement - 对保存的某个key中的值进⾏减法操作Memcache::delete - 删除⼀个key值Memcache::flush - 清除所有缓存的数据Memcache::get - 获取⼀个key值Memcache::getExtendedStats - 获取进程池中所有进程的运⾏系统统计Memcache::getServerStatus - 获取运⾏服务器的参数Memcache::getStats - 返回服务器的⼀些运⾏统计信息Memcache::getVersion - 返回运⾏的Memcache的版本信息Memcache::increment - 对保存的某个key中的值进⾏加法操作Memcache::pconnect - 创建⼀个Memcache的持久连接对象Memcache::replace -对⼀个已有的key进⾏覆写操作Memcache::set - 添加⼀个值,如果已经存在,则覆写Memcache::setCompressThreshold - 对⼤于某⼀⼤⼩的数据进⾏压缩Memcache::setServerParams - 在运⾏时修改服务器的参数Memcache::add⽤法bool Memcache::add ( string $key , mixed $var [, int $flag [, int $expire ]] )说明:如果key不存在的时候,使⽤这个函数来存储var的值。

PHP内存缓存Memcached类实例

PHP内存缓存Memcached类实例

PHP内存缓存Memcached类实例PHP内存缓存Memcached类实例PHP内存缓存Memcached类,以实例形式分析了PHP内存缓存Memcached的实现方法,是php操作memcached的典型应用,非常具有实用价值,需要的朋友可以参考下。

具体实现方法如下:复制代码代码如下:<?PHPclass MemcacheModel {private $mc = null;/*** 构造方法,用于添加服务器并创建memcahced对象*/function __construct(){$params = func_get_args();$mc = new Memcache;//如果有多个memcache服务器if( count($params) > 1){foreach ($params as $v){call_user_func_array(array($mc, 'addServer'), $v);}//如果只有一个memcache服务器} else {call_user_func_array(array($mc, 'addServer'), $params[0]);}$this->mc=$mc;}/*** 获取memcached对象* @return object memcached对象*/function getMem(){return $this->mc;}/*** 检查mem是否连接成功* @return bool 连接成功返回true,否则返回false*/function mem_connect_error(){$stats=$this->mc->getStats();if(emptyempty($stats)){return false;}else{return true;}}private function addKey($tabName, $key){$keys=$this->mc->get($tabName);if(emptyempty($keys)){$keys=array();}//如果key不存在,就添加一个if(!in_array($key, $keys)) {$keys[]=$key; //将新的key添加到本表的keys中$this->mc->set($tabName, $keys, MEMCACHE_COMPRESSED, 0);return true; //不存在返回true}else{return false; //存在返回false}}/*** 向memcache中添加数据* @param string $tabName 需要缓存数据表的表名* @param string $sql 使用sql作为memcache的key* @param mixed $data 需要缓存的数据*/function addCache($tabName, $sql, $data){$key=md5($sql);//如果不存在if($this->addKey($tabName, $key)){$this->mc->set($key, $data, MEMCACHE_COMPRESSED, 0); }}/*** 获取memcahce中保存的`数据* @param string $sql 使用SQL的key* @return mixed 返回缓存中的数据*/function getCache($sql){$key=md5($sql);return $this->mc->get($key);}/*** 删除和同一个表相关的所有缓存* @param string $tabName 数据表的表名*/function delCache($tabName){$keys=$this->mc->get($tabName);//删除同一个表的所有缓存if(!emptyempty($keys)){foreach($keys as $key){$this->mc->delete($key, 0); //0 表示立刻删除}}//删除表的所有sql的key$this->mc->delete($tabName, 0);}/*** 删除单独一个语句的缓存* @param string $sql 执行的SQL语句*/function delone($sql){$key=md5($sql);$this->mc->delete($key, 0); //0 表示立刻删除}}>希望本文所述对大家的PHP程序设计有所帮助。

PHP扩展Memcached命令用法实例总结

PHP扩展Memcached命令用法实例总结

PHP扩展Memcached命令⽤法实例总结本⽂实例讲述了PHP 扩展Memcached命令⽤法。

分享给⼤家供⼤家参考,具体如下:windows 下没有memcached的扩展,只有memcache的扩展。

亲测,两者之间还是有很⼤差别的。

所以建议还是在linux做。

<?php$mem = new Memcached();//添加⼀台服务器资源$mem->addServer('127.0.0.1', '11211');//添加多台,分布式存储,第三个参数为权重值/*$servers = array(array('127.0.0.1', 11211, 33),array('127.0.0.2', 11211, 67),);$res = $mem->addServers($servers);*///设置:键值过期时间(秒)$mem->set('name', 'huangyuxin', 5);//注意:最⼤⽣命周期可设置为60*60*24*30 三⼗天的时间//再往后的话要加上时间戳 time()+60*60*24*31(三⼗⼀天)//获取值$value = $mem->get('name');//添加值,如果存在此键,false$result = $mem->add('name','zhangsan');//追加: 键值 ,追加在⼀个已经存在的值得后⾯,不存在也为false//setOption 这⼀句必须加上,不然追加不上//prepend 前⾯追加//如果Memcached::OPT_COMPRESSION常量开启,这个操作会失败,并引发⼀个警告,因为向压缩数据后追加数据可能会导致解压不了。

$mem->setOption(Memcached::OPT_COMPRESSION, false);$mem->append('name','haha');$value = $mem->get('name');//这个是减掉元素的值,两个参数,第⼆个参数决定减掉数值⼏,默认是 1 ,increment 是加$mem->set('age', 12, 30);$mem->decrement('age');$mem->decrement('age',2);$value = $mem->get('age');//删除元素$mem->delete('age');$mem->delete('age',60);/*注意:服务端在这段时间拒绝对这个key的add和replace命令.由于这个时间段的存在, 元素被放⼊⼀个删除队列表明它不可以通过get命令获取到值但是同时 add和replace命令也从服务端内存删除(表明元素会被⽴即删除并且之后对这个 key的存储命令也会成功)*///删除多个$mem->add('age', 12, 60);$mem->add('name', 'huangyuxin', 60);$res = $mem->deleteMulti(array('age','name'));//作废 :flush不会真正的释放已有元素的内存,⽽是逐渐的存⼊新元素重⽤那些内存。

php memcached 用法

php memcached 用法

php memcached 用法“php memcached 用法”Memcached是一种高性能分布式内存对象缓存系统,常用于缓存常用数据,提高Web应用程序的性能。

在PHP中,Memcached可以通过扩展或使用Memcached类来实现。

本文将深入探讨Memcached的用法,包括安装、配置、连接、存储与获取数据、过期时间设置和常见问题解决等方面的内容。

第一步:安装和配置Memcached要使用PHP的Memcached扩展,首先需要在服务器上安装Memcached 软件包。

在Linux系统上,我们可以通过包管理器来安装。

例如,对于Ubuntu,可以使用以下命令安装:sudo apt-get install memcached安装好Memcached之后,我们需要编辑php.ini文件来启用Memcached扩展。

找到该文件(通常位于/etc/php/7.4/apache2/目录中)并打开它。

在文件中找到一个名为"extension"的行,然后在该行下面添加以下代码:extension=memcached.so保存并关闭php.ini文件。

重启Web服务器,使配置生效。

第二步:连接Memcached服务器在PHP中,我们可以通过两种方式连接到Memcached服务器:使用Memcached扩展或使用Memcached类。

以下是实现两种方法的示例代码:1. 使用Memcached扩展memcached = new Memcached();memcached->addServer('localhost', 11211);在这个例子中,我们创建了一个Memcached实例,并添加了一个服务器。

这里的localhost是Memcached服务器的主机名或IP地址,11211是Memcached服务器的默认端口号。

2. 使用Memcached类memcached = new Memcached();memcached->addServer('localhost', 11211);与使用Memcached扩展相比,使用Memcached类的代码几乎是一样的。

PHP(MysqlRedis)消息队列的介绍及应用场景案例--转载

PHP(MysqlRedis)消息队列的介绍及应用场景案例--转载

PHP(MysqlRedis)消息队列的介绍及应⽤场景案例--转载郑重提⽰:本博客转载⾃好友博客,个⼈觉得写的很⽜逼所以未经同意强⾏转载,原博客连接 /wt645631686/p/8243438.html 欢迎访问在进⾏⽹站设计的时候,有时候会遇到给⽤户⼤量发送短信,或者订单系统有⼤量的⽇志需要记录,还有做秒杀设计的时候,服务器⽆法承受这种瞬间的压⼒,⽆法正常处理,咱们怎么才能保证系统正常有效的运⾏呢?这时候我们就要引⽤消息队列来实现这类的需求,这时候就需要⼀个中间的系统进⾏分流和解压。

消息队列就是⼀个中间件,需要配合其他合理使⽤。

消息队列的概念、原理和场景本质上讲,消息队列结构就是⼀个队列结构的中间件,也就是说把消息和内容放⼊这个容器之后,就可以直接的返回,不需要等它后期处理的结果,另外会有⼀个程序会读取这些数据,并按照顺序进⾏逐个的处理,也就是说按照并发⾮常⼤的⼀个环节的时候,同时呢你⼜不需要⽴即获得这个环节的返回结果,那么使⽤消息队列可以⽐较好的解决这个问题。

⼀个经典的消息队列结果应该是这样的过程:由⼀个业务系统进⾏⼊队,把消息逐个插⼊消息队列中,插⼊成功之后直接返回成功的结果,然后后续有⼀个消息处理系统,这个系统会把消息队列中的记录逐个进⾏取出并且进⾏处理,进⾏出队的操作。

消息系统适合的场景冗余⾸先数据需要冗余的时候,⽐如经常做订单系统,后续需要严格的转换和记录,消息队列可以把这些数据持久化存储在队列中,然后由订单处理程序进⾏获取,后续处理完成之后再把这条记录删除,保证每条记录都能处理完成。

解耦消息队列分离了两套系统,解决了两套系统深度耦合的问题。

使⽤消息队列后,⼊队的系统和出队的系统没有直接的关系,⼊队系统和出队系统其中⼀套系统崩溃的时候,都不会影响到另⼀个系统的正常运转。

流量削峰这种场景最经典的就是秒杀抢购,这种情况会出现很⼤的流量剧增,⼤量的需求集中在短短的⼏秒内,对服务器的瞬间压⼒⾮常⼤,⽽我们配合缓存使⽤消息队列能⾮常有效的顶住瞬间访问量,防⽌服务器顶不住⽽崩溃。

消息队列的应用实例

消息队列的应用实例

消息队列的应⽤实例以⼀个聊天程序为例:聊天的两端分别为进程server和进程clientserver:#include <stdio.h>#include <strings.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#define PROJ_ID 11#define BUF_SIZE 256#define EXIT_CODE 1#define MSND_TYPE 1#define RCV_TYPE 2struct mymsgbuf{long msgtype;char buf[BUF_SIZE];};int main(){struct mymsgbuf msgbuf;key_t key;int pid;int len;bzero(&msgbuf, sizeof(msgbuf));len = sizeof(msgbuf) - 4;key = ftok(".", PROJ_ID);if (-1 == key){perror("ftok error:");exit(EXIT_CODE);}pid = msgget(key, IPC_CREAT|0660);if (-1 == pid){perror("msgget error:");exit(EXIT_CODE);}while(1){bzero(&msgbuf, sizeof(msgbuf));printf("server: ");fgets(msgbuf.buf, BUF_SIZE, stdin);msgbuf.buf[strlen(msgbuf.buf)-1] = '\0';msgbuf.msgtype = MSND_TYPE;len = sizeof(msgbuf) - 4;if (-1 == msgsnd(pid, &msgbuf, len, 0)){perror("msgsnd error:");break;}if ( strncmp("exit", msgbuf.buf, strlen("exit")) == 0){sleep(1);break;}bzero(&msgbuf, sizeof(msgbuf));if (-1 == msgrcv(pid, &msgbuf, BUF_SIZE, RCV_TYPE, 0)) {perror("msgrcv error:");break;}printf("recv from client message:%s\n", msgbuf.buf);}msgctl(pid, IPC_RMID, NULL);return0;}client:#include <stdio.h>#include <strings.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#define PROJ_ID 11#define BUF_SIZE 256#define EXIT_CODE 1#define MSND_TYPE 2#define RCV_TYPE 1struct mymsgbuf{long msgtype;char buf[BUF_SIZE];};int main(){struct mymsgbuf msgbuf;key_t key;int pid;int len;bzero(&msgbuf, sizeof(msgbuf));len = sizeof(msgbuf) - 4;key = ftok(".", PROJ_ID);if (-1 == key){perror("ftok error:");exit(EXIT_CODE);}pid = msgget(key, IPC_CREAT|0660);if (-1 == pid){perror("msgget error:");exit(EXIT_CODE);}while(1){bzero(&msgbuf, sizeof(msgbuf));if (-1 == msgrcv(pid, &msgbuf, BUF_SIZE, RCV_TYPE, 0)) {perror("msgrcv error:");break;}printf("recv from server message:%s\n", msgbuf.buf);if ( strncmp("exit", msgbuf.buf, strlen("exit")) == 0){break;}bzero(&msgbuf, sizeof(msgbuf));printf("client: ");fgets(msgbuf.buf, BUF_SIZE, stdin);if ( strncmp("exit", msgbuf.buf, strlen("exit")) == 0){break;}msgbuf.buf[strlen(msgbuf.buf)-1] = '\0';msgbuf.msgtype = MSND_TYPE;if (-1 == msgsnd(pid, &msgbuf, strlen(msgbuf.buf)+1, 0)){perror("msgsnd error:");break;}}return0;}。

phpMemcache中实现消息队列

phpMemcache中实现消息队列

phpMemcache中实现消息队列php Memcache中实现消息队列对于一个很大的消息队列,频繁进行进行大数据库的序列化和反序列化,有太耗费。

下面是我用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 getT op(){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; }} </p。

PHP进程间通信——消息队列(msg_queue)

PHP进程间通信——消息队列(msg_queue)

PHP进程间通信——消息队列(msg_queue)PHP 进程间通信——消息队列本⽂不涉及PHP基础库安装。

详细安装说明,请参考官⽹,或期待后续博客分享。

1、消息队列函数准备<?php//⽣成⼀个消息队列的key$msg_key = ftok(__FILE__, 'a');//产⽣⼀个消息队列$msg_queue = msg_get_queue($msg_key, 0666);//检测⼀个队列是否存在 ,返回boolean值$status = msg_queue_exists($msg_key);//可以查看当前队列的⼀些详细信息$message_queue_status = msg_stat_queue($msg_queue);//将⼀条消息加⼊消息队列msg_send($msg_queue, 1, "Hello, 1");msg_send($msg_queue, 1, 'Hello, 2');msg_send($msg_queue, 1, "Hello, 3");//从消息队列中读取⼀条消息。

msg_receive($msg_queue, 1, $message_type, 1024, $message1);msg_receive($msg_queue, 1, $message_type, 1024, $message2);msg_receive($msg_queue, 1, $message_type, 1024, $message3);//移除消息队列msg_remove_queue($msg_queue);echo $message1.PHP_EOL;echo $message2.PHP_EOL;echo $message3.PHP_EOL;/*** msg_send 有三个必选参数* resource $queue ,* int $msgtype ,* mixed $message** 第⼀个必须要是队列资源类型。

PHP使用MySQL实现消息队列

PHP使用MySQL实现消息队列

PHP使⽤MySQL实现消息队列消息队列常⽤在流量削峰(秒杀场景),异步通信等地⽅。

⼤体的结构如下: 类似于消费者和⽣产者的关系,⾸先⽣产者在消息队列未满的时候,才将⽣产的产品放进消息队列中;消费者在消息队列不为空的时候,才从消息队列中取出产品进⾏消费。

出队的那个步骤常⽤的⽅法是⼀直轮询和定时操作。

这⾥举⼀个外卖送餐的案例: 有个⽣意很好的饭店,好到什么程度呢?⼀分钟有500⼈下单,这样的话,店家掌柜肯定处理不过来,于是,就先暂时不通知⽤户是够接单,先把所有的订单先存着,只告诉他们正在处理中,但是呢,还有⼀个问题,就是有⼀些是其他饭店专门来搞事的(眼红了),所以就要查看订单是否合法。

上⾯的情景可以这样实现:⽤户下单之后,后台会创建⼀个随机的order_id对应该订单;并且该订单的初始状态(status)为待处理(0);当商家查看该订单情况时,将status改为1,表⽰正在处理;当商家确认这个订单可以接受时,就将该订单的status改为2,表⽰成功接单。

⾸先在数据库中创建⼀个order_list订单表,表结构如下:mysql> desc order_list;+----------+------------+------+-----+----------+-------+| Field | Type | Null | Key | Default | Extra |+----------+------------+------+-----+----------+-------+| order_id | int(11) | NO | PRI | NULL | || mobile | int(8) | NO | | 88888888 | || status | tinyint(1) | YES | | 0 | |+----------+------------+------+-----+----------+-------+3 rows in set (0.05 sec) 有两个PHP程序,分别是producer.php(⽤户、⽣产者); consumer.php(商家、消费者) ⼀旦有⽤户下单,就往order_list中添加⼀条数据,这⾥⽅便测试,于是执⾏下⾯的PHP程序,表⽰⽤户⽅(producer.php),每隔2秒下⼀次单;<?php$pdo=new PDO("mysql:host=localhost;dbname=test","root","root");$stmt=$pdo->prepare("insert into order_list (order_id,mobile,status) values (?,?,?)");while(1){$order_id=rand(10000,99999);$mobile=rand(11111111,99999999);$stmt->execute(array($order_id,$mobile,0));echo date("Y-m-d H:i:s",time())."添加了⼀条订单,订单号为{$order_id},⼿机号为{$mobile}\n";sleep(2);}> ⽤户提交订单后,剩下的事情就交给商家了,商家(consumer.php)⽣意太忙了,每4秒才能处理⼀个订单:<?php$pdo=new PDO("mysql:host=localhost;dbname=test","root","root");$stmt=$pdo->prepare("update order_list set status=? where status=? limit 1");$stmt_select=$pdo->prepare("select order_id from order_list where status=1");//正在处理的订单号while(1){$init=0;//初始status$lock=1;//标记为正在处理$success=2;//成功接单//为了保证数据的⼀致性,处理订单之前,要先锁定⼀个订单,将其status由0改为1,然后才可处理//处理完毕后,然后再将status从1改为2$stmt->execute(array($lock,$init));//锁定要处理的订单$stmt_select->execute();$result=$stmt_select->fetch(PDO::FETCH_ASSOC);//查询正在处理的订单号$order_id=$result['order_id'];echo date("Y-m-d H:i:s")."准备处理订单,订单号为{$order_id}\n";sleep(3);//处理3秒$stmt->execute(array($success,$lock));echo date("Y-m-d H:i:s")."订单处理完成,订单号为{$order_id}\n";sleep(1);//休息1秒}> 这样就使⽤MySQL实现了⼀个简单的消息队列,可以看⼀下如何使⽤Redis实现消息队列,与这个⽅法类似。

php+redis实现消息队列

php+redis实现消息队列

php+redis实现消息队列个⼈理解在项⽬中使⽤消息队列⼀般是有如下⼏个原因:1. 把瞬间服务器的请求处理换成异步处理,缓解服务器的压⼒2. 实现数据顺序排列获取r edis实现消息队列步骤如下:1).redis函数rpush,lpop2).建议定时任务⼊队列3)创建定时任务出队列⽂件:demo.php插⼊数据到redis队列1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17<?php$redis= new Redis();$redis->connect('127.0.0.1',6379); $password= '123456';$redis->auth($password);$arr= array('h','e','l','l','o','w','o','r','l','d'); foreach($arr as$k=>$v){$redis->rpush("mylist",$v);}执⾏后结果如下>⽂件:index.php定时扫描出队列1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19<?php$redis= new Redis();$redis->connect('127.0.0.1',6379); $password= '123456';$redis->auth($password);//list类型出队操作$value= $redis->lpop('mylist');if($value){echo"出队的值".$value;}else{1920 21 22 23 24 25 echo"出队完成"; }>建⽴定时任务*/1 * * * * root php /wwwroot/workplace/redis/index.php*/3 * * * * root php /wwwroot/workplace/redis/demo.phptail -f /var/log/cron 查看定时任务执⾏情况Nov 7 00:30:01 dongzi CROND[6888]: (root) CMD (php /wwwroot/workplace/redis/demo.php) Nov 7 00:30:01 dongzi CROND[6890]: (root) CMD (php /wwwroot/workplace/redis/index.php )定时任务执⾏队列写⼊结果如下12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21127.0.0.1:6379> lrange mylist 0 -11) "h"2) "e"3) "l"4) "l"5) "o"6) "w"7) "o"8) "r"9) "l"10) "d"定时任务执⾏出队列后:127.0.0.1:6379> lrange mylist 0 -11) "e"2) "l"3) "l"4) "o"5) "w"6) "o"7) "r"8) "l"9) "d"。

php队列写法

php队列写法

PHP简单队列实现:基于数组的操作方法在PHP中,可以使用多种方式来实现队列。

以下是一种简单的队列实现方法,使用PHP的数组和队列的基本操作。

class Queue {private $queue = [];// 入队操作public function enqueue($item) {array_push($this->queue, $item);}// 出队操作public function dequeue() {if (count($this->queue) < 1) {return null; // 队列为空时返回null}return array_shift($this->queue);}// 查看队首元素public function front() {if (count($this->queue) < 1) {return null; // 队列为空时返回null}return $this->queue[0];}// 检查队列是否为空public function isEmpty() {return count($this->queue) == 0;}// 获取队列大小public function size() {return count($this->queue);}}使用示例:$queue = new Queue();$queue->enqueue("item1"); // 入队操作$queue->enqueue("item2");$queue->enqueue("item3");echo $queue->size(); // 输出队列大小为3echo $queue->front(); // 输出队首元素"item1"$queue->dequeue(); // 出队操作,移除队首元素"item1"echo $queue->size(); // 输出队列大小为2这个示例使用了PHP的数组来实现队列,通过array_push函数进行入队操作,通过array_shift函数进行出队操作。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PHP memcache实现消息队列实例现在memcache在服务器缓存应用比较广泛,下面我来介绍memcache实现消息队列等待的一个例子,有需要了解的朋友可参考。

memche消息队列的原理就是在key上做文章,用以做一个连续的数字加上前缀记录序列化以后消息或者日志。

然后通过定时程序将内容落地到文件或者数据库。

php实现消息队列的用处比如在做发送邮件时发送大量邮件很费时间的问题,那么可以采取队列。

方便实现队列的轻量级队列服务器是:star ling支持memcache协议的轻量级持久化服务器htt ps:///starling/starlingBeanstalkd轻量、高效,支持持久化,每秒可处理3000左右的队列/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 < 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@* @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->Inc($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);*/?>对于一个很大的消息队列,频繁进行进行大数据库的序列化和反序列化,有太耗费。

相关文档
最新文档