php rabbitmq延迟队列示例
来源:互联网 发布:淘宝网退货地址怎么改 编辑:程序博客网 时间:2024/06/10 04:54
Python示例请移步
官方有关于延迟队列的插件,可以更灵活的设置延迟队列
<?php/** * Created by PhpStorm. * User: he * Date: 17-7-17 * Time: 下午5:38 */namespace AcmeBundle\Service;use PhpAmqpLib\Connection\AMQPStreamConnection;use PhpAmqpLib\Message\AMQPMessage;class RabbitBase{ /** * 场景死信收容队列 * @var array */ private static $scene_out_queue = [ self::TEST => 'test_queue', // 测试队列 ]; /** * 场景死信收容交换机 * @var array */ private static $scene_out_exchange = [ self::TEST => 'test.exchange', // 测试队列 ]; /** * 队列延迟时间 | 毫秒时间 * @var array */ private static $ttl_time = [ self::TEST => 10000, // 86400*3 ]; /** * 场景列表 * @var array */ private static $scene_list = [ 'TEST' => 'TEST', // 测试队列 ]; const TEST = 'TEST';// 测试队列 /** * 管道连接 * @type object * @var AMQPStreamConnection */ private $connection; /** * 交换机 * @type object * @var \PhpAmqpLib\Channel\AMQPChannel */ private $channel; /** * 队列名 * @var string */ private $queue_name; /** * 交换机名 * @var string */ private $exchange_name; /** * 场景参数 * @var string */ private static $time_scene; /** * 是否持久化 * @var bool */ private static $is_durable = true; /** * 是否延迟 * @var bool */ private static $is_delay = false; /** * 当前交换机 * @var string */ private static $delay_exchange; /** * 当前队列 * @var string */ private static $delay_queue; /** * 延迟队列参数 * @var array */ private static $arguments = []; /** * 交换机类型 * @var string */ private static $type = 'fanout'; /** * 0-9-1 SIG * @link http://www.rabbitmq.com/amqp-0-9-1-errata.html#section_3 * @var string */ private static $T_STRING_SHORT = 'S'; /** * 0-9-1 SIG * @link http://www.rabbitmq.com/amqp-0-9-1-errata.html#section_3 * @var string */ private static $T_INT_LONG = 'I'; /** * RabbitBase constructor. * @param array $config // mq配置参数 */ public function __construct(array $config) { $this->connection = new AMQPStreamConnection( $config['host']??'', $config['port']??'', $config['user']??'', $config['pwd']??'', $config['vhost']??'' ); if(!$this->getCloseStatus()){ // throw new \Exception('AMQP Connection fail'); echo 'ERROR: AMQP Connection Fail';exit; } $this->channel = $this->connection->channel(); } /** * 设置私有属性 * @param $name * @param $value */ public function __set($name, $value) { // TODO: Implement __set() method. $this->$name = $value; } /** * 获取私有属性 * @param $name // 属性名 * @return null */ public function __get($name) { // TODO: Implement __get() method. return isset($this->$name)? $this->$name : null; } /** * 获取场景列表 * @return array */ public function getSceneList() { return self::$scene_list; } /*****************************************************队列服务******************************************************/ /** * 打开管道 * * TODO: is_delay 是true时需后面参数 * TODO: is_delay 是true时需要 time_scene参数,否则会返回异常信息 * TODO: queue_scene 或 exchange_scene 为null时默认使用time_scene * * @param string $queue_name 队列名 * @param string $exchange_name 交换机名 * @param bool $is_receive 是否是处理程序 * @param bool $is_delay 是否延迟 * @param string|null $time_scene 延迟时间 参考 self::$ttl_time * @param string|null $queue_scene 延迟场景队列 参考 self::$scene_out_queue * @param string|null $exchange_scene 延迟场景交换机 参考 self:$scene_out_exchange * @throws \Exception * @return mixed|null|string */ public function open( string $queue_name, string $exchange_name, bool $is_receive = false, bool $is_delay = false, string $time_scene = null, string $queue_scene = null, string $exchange_scene = null ) { $this->queue_name = $queue_name; $this->exchange_name = $exchange_name; self::$time_scene = $time_scene; self::$delay_exchange = empty($exchange_scene)?$time_scene:$exchange_scene; self::$delay_queue = empty($queue_scene)?$time_scene:$queue_scene; self::$is_delay = $is_delay; try { // TODO: 设置延迟参数 self::getArguments(); // TODO: 当开始处理管道内消息时,防止管道未创建引起异常 if (true === $is_receive) { // 创建交换机 $this->getExchangeDeclare($this->exchange_name, self::$type, self::$is_durable); // 创建队列 $this->getQueueDeclare($this->queue_name, self::$is_durable, self::$arguments); // 队列和交换机绑定 $this->getQueueBind($this->queue_name, $this->exchange_name); } return true; } catch (\Exception $e){ return 'Info:'.$e->getMessage().' Line:'.$e->getLine().' File:'.$e->getFile(); } } /** * 加入队列 * @param array $data * @throws \Exception * @return bool|string */ public function send(array $data) { try{ if (empty($this->queue_name) || empty($this->exchange_name)) { throw new \Exception('arguments queue name or exchange name error'); } // TODO: Implement 创建超时收容队列和交换机 empty(self::$time_scene)?:$this->createOutQueue( self::$scene_out_queue[self::$time_scene]??'', self::$scene_out_exchange[self::$time_scene]??'' ); // TODO: Implement 创建交换机 $this->getExchangeDeclare($this->exchange_name, self::$type, self::$is_durable); // TODO: Implement 创建队列 $this->getQueueDeclare($this->queue_name, self::$is_durable, self::$arguments); // TODO: Implement 队列和交换机绑定 $this->getQueueBind($this->queue_name, $this->exchange_name); // TODO: Implement 加入消息到队列 $this->getBasicPublish($data, $this->queue_name); return $this->close(); } catch (\Exception $e){ return 'Info:'.$e->getMessage().' Line:'.$e->getLine().' File:'.$e->getFile(); } } /** * 处理队列 * @param string $queue * @param null $callback * @param string $consumer_tag * @param bool $no_local * @param bool $no_ack * @param bool $exclusive * @param bool $nowait * @param null $ticket * @param array $arguments */ public function receive( $queue = '', $callback = null, $consumer_tag = '', $no_local = false, $no_ack = false, $exclusive = false, $nowait = false, $ticket = null, $arguments = array() ) { $this->channel->basic_consume( $queue, $consumer_tag, $no_local, $no_ack, $exclusive, $nowait, $callback, $ticket, $arguments ); } /** * * Wait for some expected AMQP methods and dispatch to them. * Unexpected methods are queued up for later calls to this PHP * method. */ public function wait() { while(count($this->channel->callbacks)) { $this->channel->wait(); } } /*****************************************************私有服务******************************************************/ /** * 关闭连接 * @return bool */ private function close() { $this->closeConnection(); $this->closeChannel(); return !$this->getCloseStatus(); } /** * 创建超时队列和交换机 * @param string $queue_name * @param string $exchange_name * @throws \Exception */ private function createOutQueue(string $queue_name = '', string $exchange_name = '') { if(empty($queue_name) || empty($exchange_name)){ throw new \Exception('queue name or exchange name is empty'); } if(true === self::$is_delay){ // TODO: 创建延迟交换机 $this->getExchangeDeclare($exchange_name, self::$type, self::$is_durable); // TODO: 创建延迟队列 $this->getQueueDeclare($queue_name, self::$is_durable); // TODO: 队列和交换机绑定 $this->getQueueBind($queue_name, $exchange_name); } } /** * 设置超时转移队列参数 * @throws \Exception */ private static function getArguments() { if(true === self::$is_delay){ if(!empty(self::$delay_queue) && !empty(self::$delay_exchange)){ self::$arguments = array( "x-message-ttl" => array(self::$T_INT_LONG, self::$ttl_time[self::$time_scene]), ); self::setDelayExchange(); self::setDelayQueue(); } else { throw new \Exception(__METHOD__."delay arguments error"); } } } /** * 设置延迟队列queue * @throws \Exception */ private static function setDelayQueue() { $p = ["x-dead-letter-routing-key" => array( self::$T_STRING_SHORT, self::$scene_out_queue[self::$delay_queue]) ]; if(true === self::$is_delay && !empty(self::$delay_queue)){ self::$arguments = empty(self::$arguments)?:array_merge(self::$arguments, $p); } else { throw new \Exception(__METHOD__.'delay arguments error'); } } /** * 设置延迟队列exchange * @throws \Exception */ private static function setDelayExchange() { $p = ["x-dead-letter-exchange" => array(self::$T_STRING_SHORT, self::$scene_out_exchange[self::$delay_exchange])]; if(true === self::$is_delay && !empty(self::$delay_exchange)){ self::$arguments = empty(self::$arguments)?:array_merge(self::$arguments, $p); } else { throw new \Exception(__METHOD__.'delay arguments error'); } } /** * 关闭连接 * @return mixed|null */ private function closeConnection() { return $this->connection->close(); } /** * 关闭交换机连接 * @return mixed */ private function closeChannel() { return $this->channel->close(); } /** * 获取管道连接 * @return AMQPStreamConnection */ public function getConnect() : AMQPStreamConnection { return $this->connection; } /** * 获取交换机 * @return \PhpAmqpLib\Channel\AMQPChannel */ public function getChannel() { return $this->channel; } /** * 获取连接状态 * @return bool */ private function getCloseStatus(): bool { return (bool)$this->connection->isConnected(); } /** * 声明一个队列,不存在则创建 * @param string $queue * @param bool $passive * @param bool $durable * @param bool $exclusive * @param bool $auto_delete * @param bool $nowait * @param null $arguments * @param null $ticket * @return mixed|null */ private function getQueueDeclare( $queue = '', $durable = true, $arguments = null, $passive = false, $exclusive = false, $auto_delete = false, $nowait = false, $ticket = null ) { return $this->channel->queue_declare( $queue, $passive, $durable, $exclusive, $auto_delete, $nowait, $arguments, $ticket ); } /** * 声明一个交换机 * @param $exchange * @param $type * @param bool $passive * @param bool $durable * @param bool $auto_delete * @param bool $internal * @param bool $nowait * @param null $arguments * @param null $ticket * @return mixed|null */ private function getExchangeDeclare( $exchange, $type, $durable = true, $passive = false, $auto_delete = false, $internal = false, $nowait = false, $arguments = null, $ticket = null ) { return $this->channel->exchange_declare( $exchange, $type, $passive, $durable, $auto_delete, $internal, $nowait, $arguments, $ticket ); } /** * 加入队列 * @param $msg * @param string $exchange * @param string $routing_key * @param bool $mandatory * @param bool $immediate * @param null $ticket */ private function getBasicPublish( $msg, $exchange = '', $routing_key = '', $mandatory = false, $immediate = false, $ticket = null ) { self::message($msg, $this->queue_name); return $this->channel->basic_publish($msg, $exchange, $routing_key, $mandatory, $immediate, $ticket ); } /** * 消息转换对象 * @param $msg * @param string $queue */ private static function message(&$msg, string $queue) { if(is_array($msg)) { $msg['queue'] = $queue; $msg = serialize($msg); } if(self::$is_durable) { $msg = new AMQPMessage($msg, ['delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]); } else { $msg = new AMQPMessage($msg); } } /** * 绑定队列到交换机 * @param $queue * @param $exchange * @param string $routing_key * @param bool $nowait * @param null $arguments * @param null $ticket * @return mixed|null */ private function getQueueBind( $queue, $exchange, $routing_key = '', $nowait = false, $arguments = null, $ticket = null ) { return $this->channel->queue_bind( $queue, $exchange, $routing_key, $nowait, $arguments, $ticket ); } /** * 获取队列内信息数 * @deprecated * @return int */ public function getMessageNumber(): int { return (int)$this->getQueueDeclare( $this->queue_name, self::$is_durable)->method()->message_count(); } /** * 获取消费者数量 * @deprecated * @return int */ public function getConsumerNumber(): int { return (int)$this->getQueueDeclare( $this->queue_name, self::$is_durable)->method()->consumer_count(); }}
阅读全文
0 0
- php rabbitmq延迟队列示例
- rabbitmq 延迟队列的实现(PHP)
- python rabbitmq 延迟队列
- rabbitmq实现延迟队列
- 基于 rabbitmq 实现延迟队列
- RabbitMQ如何实现延迟队列?
- 基于 rabbitmq 实现延迟队列
- 延迟队列DelayQueue示例
- RabbitMQ工作队列示例
- PHP+RabbitMq示例展示
- rabbitmq PHP代码示例
- php RabbitMQ消息队列
- rabbitmq 实现延迟队列(ttl+DLX)
- RabbitMQ使用场景练习:延迟队列(八)
- Spring集成RabbitMQ并实现延迟队列
- C#实现rabbitmq 延迟队列功能
- Spring MVC整合RabbitMQ实现延迟队列
- 消息队列-RabbitMq(PHP)
- java运算符优先级记忆口诀
- IK分词原理深度解析
- uva 10763
- JAVA 多态、继承、super关键字 day9
- PDF页面大小不统一
- php rabbitmq延迟队列示例
- ubuntu django搭建网站3
- column 'typeid' in where clause is ambiguous
- as 端口占用,不能连接虚拟机
- 前端JS知识要点总结(5)
- (OK) VNCserver
- 0719学习总结(文件流的输入输出)
- 微软面试100题2010年版全部答案集锦(含下载地址)
- 【吹B不如多学习】android系统目录