hyperf中使用rabbitMQ延迟队列

1,首先确保rabbitmq安装了延迟队列插件

2,然后上代码,

先增加一个交换机类型:

<?php
/**
 * Created by PhpStorm.
 * User: haojin
 * Date: 2020/7/9
 * Time: 18:06
 */


namespace Chungou\Core\Amqp\Delay;


use Hyperf\Amqp\Message\Type;

class kinds extends Type
{
    const X_DELAYED_MESSAGE = "x-delayed-message";

    public static function all()
    {
        return [
            self::DIRECT,
            self::FANOUT,
            self::TOPIC,
            self::X_DELAYED_MESSAGE,
        ];
    }
}

 

这是消费者代码

<?php
namespace Chungou\Core\Amqp\Delay;

use Hyperf\Amqp\Builder\ExchangeBuilder;
use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\Amqp\Message\Message;
use PhpAmqpLib\Wire\AMQPTable;

//延迟队列
abstract class DelayConsumer extends ConsumerMessage
{
    protected $type = 'x-delayed-message';

    protected $delayType = "topic";

    protected $argments = [];

    public function setType(string $type): Message
    {
        if (!in_array($type, kinds::all())) {
            throw new \InvalidArgumentException(sprintf('Invalid type %s, available valus [%s]', $type,
                implode(',', kinds::all())));
        }
        $this->type = $type;
        return $this;
    }

    public function getExchangeBuilder(): ExchangeBuilder
    {
        $this->argments = array_merge($this->argments, ['x-delayed-type' => $this->delayType]);
        return (new ExchangeBuilder())->setExchange($this->getExchange())->setType($this->getType())->setArguments
        (new AMQPTable($this->argments));
    }

}

生产者:

<?php declare(strict_types=1);
/**
 * Created by PhpStorm.
 * User: haojin
 * Date: 2020/6/18
 * Time: 20:50
 */


namespace Chungou\Core\Amqp\Delay;


use Hyperf\Amqp\Builder\ExchangeBuilder;
use Hyperf\Amqp\Message\Message;
use Hyperf\Amqp\Message\ProducerMessage;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;

//延迟队列
abstract class DelayProducer extends ProducerMessage
{
    protected $type = 'x-delayed-message';

    protected $delayType = "topic";

    protected $argments = [];

    /**
     * DelayProducer constructor.
     * @param $data
     * @param int $delay 延迟发送时间 毫秒
     */
    public function __construct($data, int $delay = 0)
    {
        $this->payload = $data;
        $this->properties['application_headers'] = new AMQPTable(['x-delay' => $delay]);
        $this->properties['delivery_mode'] = AMQPMessage::DELIVERY_MODE_PERSISTENT;
    }

    public function setType(string $type): Message
    {
        if (!in_array($type, kinds::all())) {
            throw new \InvalidArgumentException(sprintf('Invalid type %s, available valus [%s]', $type,
                implode(',', kinds::all())));
        }
        $this->type = $type;
        return $this;
    }

    public function getExchangeBuilder(): ExchangeBuilder
    {
        $this->argments = array_merge($this->argments, ['x-delayed-type' => $this->delayType]);
        return (new ExchangeBuilder())->setExchange($this->getExchange())->setType($this->getType())->setArguments
        (new AMQPTable($this->argments));
    }

}

 

只需要继承这两个类就可以了

使用demo:

先定义一个生产者

<?php


namespace App\Amqp\Producer;


use Chungou\Core\Amqp\Delay\DelayProducer;
use Hyperf\Amqp\Annotation\Producer;

/**
 * 延迟生产者
 * @Producer(exchange="delayPlaceOrderExchange", routingKey="placeOrder")
 */
class DelayPlaceOrderProducer extends DelayProducer
{
}

 

定义一个消费者: 

<?php declare(strict_types=1);
/**
 * Created by PhpStorm.
 * User: haojin
 * Date: 2020/6/16
 * Time: 11:34
 */

namespace App\Amqp\Consumer;

use App\Amqp\Producer\DelayPlaceOrderProducer;
use Chungou\Core\Amqp\Delay\DelayConsumer;
use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Producer;
use Hyperf\Amqp\Result;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;

/**
 * insert订单,失败的话加入延迟队列
 * @Consumer(exchange="delayPlaceOrderExchange", routingKey="placeOrder", queue="delayPlaceOrderQueue",
 *     name="placeOrder", nums=2)
 */
class PlaceOrderConsumer extends DelayConsumer
{

    public function __construct(LoggerFactory $loggerFactory)
    {
        $this->poolName = 'default';
        $this->logger = $loggerFactory->get('log', 'default');
    }

    public function consume($data): string
    {
        //如果小于5次则重发,并且每次延迟时间 多3秒
        if ($data['retry'] <= 5) {
            $delay = $data['retry'] * 3000;
            $data['retry']++;
            
            $producer = ApplicationContext::getContainer()->get(Producer::class);
            $producer->produce(new DelayPlaceOrderProducer($data, $delay));
        }

        return Result::ACK;
    }
}

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值