httpsqs配置记录&php client
什么是httpsqs?
基于http的开源队列服务,使用Tokyo Cabinet 的 B+Tree Key/Value来做持久化存储。
适用于什么应用场景?
比较适合于比较慢而又没有特别高的时效性的应用。比如发送邮件(用户进行了某个操作,需要发送邮件给他的email账户通知。)、图片裁剪、视频转换、日志记录等。这些时效性要求不怎么高,这样就可以采用异步方式 ,让后台来集中处理,可以降低前台的服务压力。
具有什么特点?
支持http GET/POST协议,所以支持HTTP协议的都可以和他通信。
非常快速
高并发
更加详细的内容见官方网站:http://blog.s135.com/httpsqs/
官方提供了两种php client。1)php扩展(门槛高、不使用于win下的用户) 2)httpsqs_client.php (这个代码真不敢恭维)。所以自己写了一个httpsqs的类,供大家使用。
<!--?php class Httpsqs{ private $host; private $port; private $auth; private $charset; private static $sockets=array(); public function __construct($host,$port,$auth='',$charset='utf-8'){ $this--->host = $host; $this->port = $port; $this->auth = $auth; $this->charset = $charset; } public function get($name,$kt=0){ $query = $this->build_query($name,'get'); return $this->execute($query,'GET','',$kt); } public function put($name,$body,$kt=0){ $query = $this->build_query($name,'put'); return $this->execute($query,'POST',$body,$kt); } public function reset($name){ $query = $this->build_query($name,'reset'); $r = $this->execute($query); if($r && $r['data'] == "HTTPSQS_RESET_OK"){ return true; } else return false; } public function status($name,$type='text'){ if($type=='json'){ $cmd = 'status_json'; } else{ $cmd = 'status'; } $query = $this->build_query($name,$cmd); $r = $this->execute($query); if($r== false || $r['data']==false || $r['data']=='HTTPSQS_ERROR'){ return false; } return $r['data']; } public function view($name,$pos){ $query = $this->build_query($name,'view',array("pos=".$pos)); $r = $this->execute($query); if($r==false || $r['data']==false || $r['data']=='HTTPSQS_ERROR'){ return false; } else return $r['data']; } private function build_query($name,$cmd,$extra=array()){ $tmp = array("name=".$name,"opt=".$cmd); if($this->auth){ $tmp[]="auth=".$this->auth; } $tmp[]="charset=".$this->charset; $tmp = array_merge($tmp , $extra); return '/?'.implode('&',$tmp); } private function execute($query,$type='GET',$body='',$kt=0){ if($kt==1){ $key = md5($this->host.':'.$this->port); if(!isset(self::$sockets[$key])){ self::$sockets[$key] = fsockopen($this->host,$this->port,$error,$errstr,5); } $socket = self::$sockets[$key]; } else{ $socket = fsockopen($this->host,$this->port,$error,$errstr,5); } if(!$socket){ return false; } $out = "{$type} {$query} HTTP/1.1\r\n"; $out .="Host: {$this->host}\r\n"; if($type=='POST'){ $out.="Content-Length: ".strlen($body)."\r\n"; } if($kt==0){ $out .="Connection: close\r\n"; } else{ $out .="Connection: Keep-Alive\r\n"; } $out .="\r\n"; if($type=='POST' && $body){ $out .=$body; } fwrite($socket,$out); $line = trim(fgets($socket)); list($proto,$rcode,$result) = explode(" ",$line); $len = -1; $pos_value = 0; while(($line = trim(fgets($socket)))!=""){ if(strstr($line,'Content-Length:')){ list($cl,$len) = explode(" ",$line); } elseif(strstr($line,"Pos:")){ list($pos_key,$pos_value) = explode(" ",$line); } } if($len<0){ return false; } $body = @fread($socket,$len); if($kt==0){ fclose($socket); } return array( 'pos'=>intval($pos_value), 'data'=>$body ); } }
使用demo:
//get $httpsqs = new Httpsqs('192.168.219.128','1218'); $r = $httpsqs->get('my_query'); //put $httpsqs = new Httpsqs('192.168.219.128','1218'); $r = $httpsqs->put('my_query',"my_query_value"); //其他的请看源码
后感:
这个队列服务真的很实用,以前也有不少类似的应用,可以异步操作,实现方式是通过日志,比如每5分钟创建一个日志文件,然后每隔5分钟来处理,这样的风险很大,很可能造成数据的丢失等。有了这个,居多的应用都可以实现,异步发邮件,异步打日志,异步裁剪图片等等。
分类: php