tp使用Rabbitmq实例-即时队列

延时重发队列戳这里>延时限制次数重发队列

Tp6操作Rabbitmq实例 直连模式 direct

win本地安装

官网下载 erlang和rabbitmq
rabbitmq下载地址
erlang下载地址

启动rabbitmq
tp使用Rabbitmq实例-即时队列_第1张图片
tp使用Rabbitmq实例-即时队列_第2张图片
进入rabbitmq控制台
控制台链接

tp使用Rabbitmq实例-即时队列_第3张图片

composer 安装amqp类库
composer requirer php-amqplib/php-amqplib

整合rabbitmq代码


declare(strict_types=1);

namespace xxx\rabbitmq;

use ErrorException;
use Exception;
use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;

class RabbitMQ
{
    static private $instance;

    private   $host     = '127.0.0.1';
    private   $port     = 5672;
    private   $user     = 'guest';
    private   $password = 'guest';
    private   $vhost    = '/';
    protected $connection;
    protected $channel;

    /**
     * RabbitMQ constructor.
     * @param array $config
     */
    public function __construct(array $config = [])
    {
        !empty($config['host']) && $this->host = $config['host'];
        !empty($config['port']) && $this->host = $config['port'];
        !empty($config['user']) && $this->host = $config['user'];
        !empty($config['password']) && $this->host = $config['password'];
        !empty($config['vhost']) && $this->host = $config['vhost'];

        $this->connection = new AMQPStreamConnection($this->host, $this->port, $this->user, $this->password, $this->vhost);
        $this->channel    = $this->connection->channel();
    }

    /**
     * 实例化
     * @param array $config
     * @return RabbitMQ
     */
    public static function instance(array $config = [])
    {
        if (!self::$instance instanceof self) {
            self::$instance = new self($config);
        }
        return self::$instance;
    }

    /**
     * 防止被外部复制
     */
    private function __clone()
    {
    }

    /**
     * 获取信道
     * @return AMQPChannel
     */
    public function getChannel()
    {
        return $this->channel;
    }

    /**
     * 声明一个交换器
     * @param string $exchangeName 名称
     * @param string $type         交换机类型 :直连交换机(direct) 主题交换机 (topic) 头交换机(headers) 扇交换机(fanout)
     * @param bool   $pasive       是否检测同名队列
     * @param bool   $durable      是否开启队列持久化
     * @param bool   $autoDelete   通道关闭后是否删除队列
     */
    public function createExchange(
        string $exchangeName,
        string $type,
        bool $pasive = false,
        bool $durable = false,
        bool $autoDelete = false
    )
    {
        $this->channel->exchange_declare($exchangeName, $type, $pasive, $durable, $autoDelete);
    }

    /**
     * 创建队列
     * @param string $queueName
     * @param bool   $pasive
     * @param bool   $durable
     * @param bool   $exlusive
     * @param bool   $autoDelete
     * @param bool   $noWait
     * @param array  $arguments
     * @return mixed|null
     */
    public function createQueue(
        string $queueName,
        bool $pasive = false,
        bool $durable = false,
        bool $exlusive = false,
        bool $autoDelete = false,
        bool $noWait = false,
        array $arguments = []
    )
    {
        $args = [];
        if (!empty($arguments)) {
            $args = new AMQPTable();
            foreach ($arguments as $key => $value) {
                $args->set($key, $value);
            }
        }

        return $this->channel->queue_declare($queueName, $pasive, $durable, $exlusive, $autoDelete, $noWait, $args);
    }

    /**
     * 绑定队列
     * @param string   $queue
     * @param string   $exchangeName
     * @param string   $routeKey
     * @param bool     $noWait
     * @param array    $arguments
     * @param int|null $ticket
     */
    public function bindQueue(
        string $queue,
        string $exchangeName,
        string $routeKey = '',
        bool $noWait = false,
        array $arguments = [],
        $ticket = null
    )
    {
        $this->channel->queue_bind($queue, $exchangeName, $routeKey, $noWait, $arguments, $ticket);
    }

    /**
     * 生成信息
     * @param string $message    消息体
     * @param string $exchange   交换机
     * @param string $routeKey   路由key
     * @param array  $properties 属性
     * @param array  $headers
     */
    public function producerMessage(string $message, string $exchange, string $routeKey, array $properties = [], array $headers = [])
    {
        $data = new AMQPMessage($message, $properties);

        if (!empty($headers)) {
            $application_headers = new AMQPTable($headers);
            $data->set('application_headers', $application_headers);
        }

        $this->channel->basic_publish($data, $exchange, $routeKey);
    }

    /**
     * 消费消息
     * @param string $queueName
     * @param        $callback
     * @param string $tag
     * @param bool   $noLocal
     * @param bool   $noAck
     * @param bool   $exclusive
     * @param bool   $noWait
     * @throws ErrorException
     */
    public function consumeMessage(
        string $queueName,
        $callback,
        string $tag = '',
        bool $noLocal = false,
        bool $noAck = false,
        bool $exclusive = false,
        bool $noWait = false
    )
    {
        //只有consumer已经处理并确认了上一条message时queue才分派新的message给它
        $this->channel->basic_qos(null, 1, null);
        $this->channel->basic_consume($queueName, $tag, $noLocal, $noAck, $exclusive, $noWait, $callback);
        while ($this->channel->is_consuming()) {
            $this->channel->wait();
        }
    }

    /**
     * 关闭通道及链接
     * @throws Exception
     */
    public function __destruct()
    {
        //关闭通道
        $this->channel->close();
        //关闭链接
        $this->connection->close();
    }
}

使用

生产者队列:
		$rabbitmq      = new RabbitMQ();
        $route_key     = 'xxx';
        $exchange_name = 'xxx';
        $rabbitmq->createExchange($exchange_name, AMQPExchangeType::DIRECT, false, true, false);
        $data = [
            xxx
        ];
        $rabbitmq->producerMessage(json_encode($data, JSON_UNESCAPED_UNICODE), $exchange_name, $route_key, [
            'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT //消息持久化,重启rabbitmq,消息不会丢失
        ]);
消费者队列:


/*
 * author hzbskak
 * email  [email protected]
 * date   2021/4/12
 */

namespace XXXX;


use ErrorException;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;

/**
 * XXX
 * Class XXX
 * @package XXXX
 */
class XXX extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName( 'xxxx')
            ->setDescription( 'xxxx');
    }

    /**
     *
     * @param Input $input
     * @param Output $output
     * @return int|void|null
     */
    protected function execute(Input $input, Output $output)
    {
        // 指令输出
        $rabbit = new RabbitMQ();

        $exchange_name = 'xxx';
        $queue_name    = 'xxx';
        $route_key     = 'xxx';//消费规则定义
        //创建队列
        $rabbit->createQueue($queue_name, false, true);
        //绑定到交换机
        $rabbit->bindQueue($queue_name, $exchange_name, $route_key);

        //消费
        $callback = function ($message) use ($output) {
            $output->writeln('Received Message : ' . $message->body . ' Received Time : ' . date('Y-m-d H:i:s'));

            $data = json_decode($message->body, true); // 接收参数
          
            $message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);//ack
        };

        try {
            $rabbit->consumeMessage($queue_name, $callback);
        } catch (ErrorException $e) {
            echo $e->getMessage();
        }

        $output->writeln('salesConsumer');
    }
}
console.php配置文件:

// +----------------------------------------------------------------------
// | 控制台配置
// +----------------------------------------------------------------------
return [
    // 指令定义
    'commands' => [
        'test:xxx'        => "xxx\\command\\xxx\\xxx",// xxx
    ],
];

cli执行:
先用命令 php think 查看是否有 test:xxx 命令
执行队列:php think test:xxx

你可能感兴趣的:(php,rabbitmq,rabbitmq,交换机,队列,php)