PHP memcache Implementing Message Queuing instances
now memcache in the server cache application is more extensive, let me introduce the memcache implementation of Message Queuing An example, there is a need to understand the friend can refer to.
The principle of Memche Message Queuing is to make a fuss over the key to do a sequential number plus the prefix to record the message or log after serialization. The content is then dropped to a file or database via a timed program.
The use of PHP for Message Queuing, such as sending a large number of messages to send a lot of mail time-consuming problem, then you can take the queue.
A lightweight queue server that is easy to implement queues is:
Starling lightweight Persistent server with Memcache protocol support
Https://github.com/starling/starling
BEANSTALKD is lightweight, efficient, durable, capable of processing around 3000 queues per second
http://kr.github.com/beanstalkd/
You can also use memcache/memcached to implement Message Queuing in PHP.
Connect (' 127.0.0.1 ', 11211);} return $MC;} /*** The MC counter, increments the count and returns the new count * @param string $key counter * @param int $offset count increment, can be negative. 0 does not change the count * @param int $time time * @retur n int/false failure is the return of false, the count after the update counter is returned */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;} /*** Write Queue * @param string $key * @param mixed $value * @return bool*/static Public Function input ($key, $value) {$MC = self: : Mc_init (); $w _key = self::P refix. $key. ' W '; $v _key = self::P refix. $key. Self::set_counter ($w _key, 1); return $MC->set ($v _key, $value);} /*** read data in queue * @param string $key * @param int $max Maximum number of reads * @return array*/static Public Function output ($key, $max = 100) {$out = array (); $MC =Self::mc_init (); $r _key = self::P refix. $key. "R"; $w _key = self::P refix. $key. ' W '; $r _p = Self::set_counter ($r _key, 0);//Read Pointer $w_p = Self::set_counter ($w _key, 0);//write pointer if ($r _p = = 0) $r _p = 1;while ($w _p >= $r _p) {if (--$max < 0) break ; $v _key = self::P refix. $key. $r _p; $r _p = Self::set_counter ($r _key, 1); $out [] = $MC->get ($v _key); $MC->delete ($v _k EY);} return $out;}} /** Use method: Qmc::input ($key, $value);//write Queue $list = Qmc::output ($key);//Read Queue */?>
Message Queuing based on PHP shared memory implementation:
Shmid = Shmop_open ($shmkey, "C", 0644, $this->memsize); $this->maxqsize = $this->memsize/$this->blocksize ;//shen? A semaphore $this->semid = Sem_get ($shmkey, 1); Sem_acquire ($this->semid); Application for entry into the critical section $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) {//Team full 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) {//team NULL 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); Out of the critical area, releasing the semaphore}}/*//into the team operation $SHMQ = new Shmqueue (); $data = ' test data '; $shmq->enqueue ($data); unset ($SHMQ);//exit Operation $SHMQ = n EW Shmqueue (); $data = $shmq->dequeue (); unset ($SHMQ);*/?>
For a large message queue, it is too expensive to serialize and deserialize large databases frequently. Here is a message queue I implemented in PHP, only need to insert a data at the end of the operation of the tail, do not operate the entire message queue to read, and operation. However, this message queue is not thread-safe, I just try to avoid the possibility of conflict. If the message is not very dense, such as a few seconds to one, you can still consider this use.
If you want to implement thread-safe, one suggestion is to lock through the file and then do the operation. Here's the code :
The code is as follows:
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 F Irst. "); $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); ret Urn $this; } function IsEmpty () {return $this->size = = 0;} function isfull () {return $this->size = = $this->maxsize;} fun Ction EnQueue ($data) {if ($this->isfull ()) {throw new Exception ("Queue is full"), $this->increment ("size"); $thi S->set ($this->real, $data); $this->set ("real", ($this->real + 1)% $this->maxsize); return $this; } function DeQueue () {if ($this->isempty ()) {throw new Exception ("Queue isEmpty "); } $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 [] = $thi S->getkeybypos (($this->front + $offset)% $this->maxsize); $num = 1; for ($pos = ($this->front + $offset + 1)% $this->maxsize; $pos! = $this->real; $pos = ($pos + 1)% $this->max Size) {$keys [] = $this->getkeybypos ($pos), $num + +, if ($limit > 0 && $limit = = $num) {break;}} return AR Ray_values ($this->memcache->get ($keys)); } function Makeempty () {$keys = $this->getallkeys (); foreach ($keys as $value) {$this->delete ($value);} $this-> ;d elete ("real"); $this->delete ("front"); $this->delete ("size"); $this->delete ("maxSize"); } privatefunction 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;} pri vate 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) {RE Turn $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; } }