php的memcache类分享(memcache队列)的解决办法
内容摘要
这篇文章主要为大家详细介绍了php的memcache类分享(memcache队列)的简单示例,具有一定的参考价值,可以用来参考一下。
感兴趣的小伙伴,下面一起跟随php教程的小玲来看看吧!
mem
感兴趣的小伙伴,下面一起跟随php教程的小玲来看看吧!
mem
文章正文
这篇文章主要为大家详细介绍了php的memcache类分享(memcache队列)的简单示例,具有一定的参考价值,可以用来参考一下。
感兴趣的小伙伴,下面一起跟随php教程的小玲来看看吧!
memcacheQueue.class.php
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | <code><?php /* php教程 www.512Pic.com */ /** * PHP memcache 队列类 * @author LKK/lianq.net * @version 0.3 * @修改说明: * 1.放弃了之前的AB面轮值思路,使用类似数组的构造,重写了此类. * 2.队列默认先进先出,但增加了反向读取功能. * 3.感谢网友FoxHunter提出的宝贵意见. * @example: * $obj = new memcacheQueue('duilie'); * $obj->add('1asdf'); * $obj->getQueueLength(); * $obj->read(10); * $obj->get(8); */ class memcacheQueue{ public static $client ; //memcache客户端连接 public $access ; //队列是否可更新 private $expire ; //过期时间,秒,1~2592000,即30天内 private $sleepTime ; //等待解锁时间,微秒 private $queueName ; //队列名称,唯一值 private $retryNum ; //重试次数,= 10 * 理论并发数 public $currentHead ; //当前队首值 public $currentTail ; //当前队尾值 const MAXNUM = 20000; //最大队列数,建议上限10K const HEAD_KEY = '_lkkQueueHead_' ; //队列首kye const TAIL_KEY = '_lkkQueueTail_' ; //队列尾key const VALU_KEY = '_lkkQueueValu_' ; //队列值key const LOCK_KEY = '_lkkQueueLock_' ; //队列锁key /** * 构造函数 * @param string $queueName 队列名称 * @param int $expire 过期时间 * @param array $config memcache配置 * * @return <type> */ public function __construct( $queueName = '' , $expire =0, $config = '' ){ if ( empty ( $config )){ self:: $client = memcache_pconnect( '127.0.0.1' ,11211); } elseif ( is_array ( $config )){ //array('host'=>'127.0.0.1','port'=>'11211') self:: $client = memcache_pconnect( $config [ 'host' ], $config [ 'port' ]); } elseif ( is_string ( $config )){ //"127.0.0.1:11211" $tmp = explode ( ':' , $config ); $conf [ 'host' ] = isset( $tmp [0]) ? $tmp [0] : '127.0.0.1' ; $conf [ 'port' ] = isset( $tmp [1]) ? $tmp [1] : '11211' ; self:: $client = memcache_pconnect( $conf [ 'host' ], $conf [ 'port' ]); } if (!self:: $client ) return false; ignore_user_abort(true); //当客户断开连接,允许继续执行 set_time_limit(0); //取消脚本执行延时上限 $this ->access = false; $this ->sleepTime = 1000; $expire = empty ( $expire ) ? 3600 : intval ( $expire )+1; $this ->expire = $expire ; $this ->queueName = $queueName ; $this ->retryNum = 1000; $this ->head_key = $this ->queueName . self::HEAD_KEY; $this ->tail_key = $this ->queueName . self::TAIL_KEY; $this ->lock_key = $this ->queueName . self::LOCK_KEY; $this ->_initSetHeadNTail(); } /** * 初始化设置队列首尾值 */ private function _initSetHeadNTail(){ //当前队列首的数值 $this ->currentHead = memcache_get(self:: $client , $this ->head_key); if ( $this ->currentHead === false) $this ->currentHead =0; //当前队列尾的数值 $this ->currentTail = memcache_get(self:: $client , $this ->tail_key); if ( $this ->currentTail === false) $this ->currentTail =0; } /** * 当取出元素时,改变队列首的数值 * @param int $step 步长值 */ private function _changeHead( $step =1){ $this ->currentHead += $step ; memcache_set(self:: $client , $this ->head_key, $this ->currentHead,false, $this ->expire); } /** * 当添加元素时,改变队列尾的数值 * @param int $step 步长值 * @param bool $reverse 是否反向 * @return null */ private function _changeTail( $step =1, $reverse =false){ if (! $reverse ){ $this ->currentTail += $step ; } else { $this ->currentTail -= $step ; } memcache_set(self:: $client , $this ->tail_key, $this ->currentTail,false, $this ->expire); } /** * 队列是否为空 * @return bool */ private function _isEmpty(){ return (bool)( $this ->currentHead === $this ->currentTail); } /** * 队列是否已满 * @return bool */ private function _isFull(){ $len = $this ->currentTail - $this ->currentHead; return (bool)( $len === self::MAXNUM); } /** * 队列加锁 */ private function _getLock(){ if ( $this ->access === false){ while (!memcache_add(self:: $client , $this ->lock_key, 1, false, $this ->expire) ){ usleep( $this ->sleepTime); @ $i ++; if ( $i > $this ->retryNum){ //尝试等待N次 return false; break ; } } $this ->_initSetHeadNTail(); return $this ->access = true; } return $this ->access; } /** * 队列解锁 */ private function _unLock(){ memcache_delete(self:: $client , $this ->lock_key, 0); $this ->access = false; } /** * 获取当前队列的长度 * 该长度为理论长度,某些元素由于过期失效而丢失,真实长度<=该长度 * @return int */ public function getQueueLength(){ $this ->_initSetHeadNTail(); return intval ( $this ->currentTail - $this ->currentHead); } /** * 添加队列数据 * @param void $data 要添加的数据 * @return bool */ public function add( $data ){ if (! $this ->_getLock()) return false; if ( $this ->_isFull()){ $this ->_unLock(); return false; } $value_key = $this ->queueName . self::VALU_KEY . strval ( $this ->currentTail +1); $result = memcache_set(self:: $client , $value_key , $data , MEMCACHE_COMPRESSED, $this ->expire); if ( $result ){ $this ->_changeTail(); } $this ->_unLock(); return $result ; } /** * 读取队列数据 * @param int $length 要读取的长度(反向读取使用负数) * @return array */ public function read( $length =0){ if (! is_numeric ( $length )) return false; $this ->_initSetHeadNTail(); if ( $this ->_isEmpty()){ return false; } if ( empty ( $length )) $length = self::MAXNUM; //默认所有 $keyArr = array (); if ( $length >0){ //正向读取(从队列首向队列尾) $tmpMin = $this ->currentHead; $tmpMax = $tmpMin + $length ; for ( $i = $tmpMin ; $i <= $tmpMax ; $i ++){ $keyArr [] = $this ->queueName . self::VALU_KEY . $i ; } } else { //反向读取(从队列尾向队列首) $tmpMax = $this ->currentTail; $tmpMin = $tmpMax + $length ; for ( $i = $tmpMax ; $i > $tmpMin ; $i --){ $keyArr [] = $this ->queueName . self::VALU_KEY . $i ; } } $result = @memcache_get(self:: $client , $keyArr ); return $result ; } /** * 取出队列数据 * @param int $length 要取出的长度(反向读取使用负数) * @return array */ public function get( $length =0){ if (! is_numeric ( $length )) return false; if (! $this ->_getLock()) return false; if ( $this ->_isEmpty()){ $this ->_unLock(); return false; } if ( empty ( $length )) $length = self::MAXNUM; //默认所有 $length = intval ( $length ); $keyArr = array (); if ( $length >0){ //正向读取(从队列首向队列尾) $tmpMin = $this ->currentHead; $tmpMax = $tmpMin + $length ; for ( $i = $tmpMin ; $i <= $tmpMax ; $i ++){ $keyArr [] = $this ->queueName . self::VALU_KEY . $i ; } $this ->_changeHead( $length ); } else { //反向读取(从队列尾向队列首) $tmpMax = $this ->currentTail; $tmpMin = $tmpMax + $length ; for ( $i = $tmpMax ; $i > $tmpMin ; $i --){ $keyArr [] = $this ->queueName . self::VALU_KEY . $i ; } $this ->_changeTail( abs ( $length ), true); } $result = @memcache_get(self:: $client , $keyArr ); foreach ( $keyArr as $v ){ //取出之后删除 @memcache_delete(self:: $client , $v , 0); } $this ->_unLock(); return $result ; } /** * 清空队列 */ public function clear(){ if (! $this ->_getLock()) return false; if ( $this ->_isEmpty()){ $this ->_unLock(); return false; } $tmpMin = $this ->currentHead--; $tmpMax = $this ->currentTail++; for ( $i = $tmpMin ; $i <= $tmpMax ; $i ++){ $tmpKey = $this ->queueName . self::VALU_KEY . $i ; @memcache_delete(self:: $client , $tmpKey , 0); } $this ->currentTail = $this ->currentHead = 0; memcache_set(self:: $client , $this ->head_key, $this ->currentHead,false, $this ->expire); memcache_set(self:: $client , $this ->tail_key, $this ->currentTail,false, $this ->expire); $this ->_unLock(); } /* * 清除所有memcache缓存数据 */ public function memFlush(){ memcache_flush(self:: $client ); } } //end class</code> |
注:关于php的memcache类分享(memcache队列)的简单示例的内容就先介绍到这里,更多相关文章的可以留意
代码注释