PHP使用rabbitmq完成订单延时取消

操作环境 windows下的docker desktop

链接: docker desktop 下载地址
选择自己对应的版本进行下载

安装rabbitmq

# 拉rabbitmq 镜像
docker pull rabbitmq:management
# 运行容器
# 主要注意 15672  5672 两个端口 后边需要用到
docker run -d --name my-rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq:management
# 运行完之后  浏览器测试 账号 guest  密码 guest 测试是否安装成功
http://localhost:15672/

在这里插入图片描述

需要使用延时队列 rabbitmq 安装对应的插件

  1. 进入rabbitmq命令行
# 更新apt
apt update
# 安装wget 
apt install wget
# 下载对应的包
wget https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/3.10.2/rabbitmq_delayed_message_exchange-3.10.2.ez
# copy包到指定位置
cp rabbitmq_delayed_message_exchange-3.10.2.ez /opt/rabbitmq/plugins/
# 运行命令生效 延时队列
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
# 重启rabbitmq服务

  1. 出现对应的信息
    在这里插入图片描述

安装hyperf

# -v D:\hyperf\rabbitmq:/data/project  切换成自己本地的地址
docker run --name hyperf-rabbitmq -v D:\hyperf\rabbitmq:/data/project -p 9501:9501  -it --privileged -u root --entrypoint sh hyperf/hyperf:7.4-alpine-v3.11-swoole
# 进入容器后  切换镜像这里使用阿里镜像没有安装成功 切换成腾讯镜像好了
composer config -g repos.packagist composer https://mirrors.cloud.tencent.com/composer/
# 进入文件夹内  创建项目 项目配置 全部默认回车就可以了 有兴趣的可以自己研究
cd /data/project
composer create-project hyperf/hyperf-skeleton
# 启动项目
cd hyperf-skeleton
php bin/hyperf.php start
# 验证hyperf安装成功
127.0.0.1:9501

在这里插入图片描述

安装amqp组件

# 根据文档安装组件
composer require hyperf/amqp
# 生成配置文件
php bin/hyperf.php vendor:publish hyperf/amqp

创建数据库 生成订单

  1. 这个数据库就是一些简单的字段可以完成我们的功能即可
    在这里插入图片描述

  2. 订单模型

# 生成订单模型 这里也可以使用简单的DB类完成
php bin/hyperf.php gen:model hy_order
  1. 订单生成代码
<?php

declare(strict_types=1);
namespace App\Controller;
use App\Model\HyOrder;
class IndexController extends AbstractController
{
    public function createOrder(){
        $order = new HyOrder();
        $order_data = [
            'orderCode'=>time(),
            'status'=>1
        ];
        $order->orderCode = $order_data['orderCode'];
        $order->status = $order_data['status'];
        $order->save();
        return "success";
    }
}

根据hyperf文档下载demo文件

# 投递消息demo
php bin/hyperf.php gen:amqp-producer DelayDirectProducer
# 消息消费demo
php bin/hyperf.php gen:amqp-consumer DelayDirectConsumer

对DelayDirectProducer进行修改

根据hyperf文档进行修改就可以了 链接: hyperf文档地址

<?php

declare(strict_types=1);

namespace App\Amqp\Producer;

use Hyperf\Amqp\Annotation\Producer;
use Hyperf\Amqp\Message\ProducerMessage;
use Hyperf\Amqp\Message\ProducerDelayedMessageTrait;
use Hyperf\Amqp\Message\Type;

/**
 * @Producer()
 */
class DelayDirectProducer extends ProducerMessage
{
    use ProducerDelayedMessageTrait;
    protected $exchange = 'ext.hyperf.delay';
    protected $type = Type::DIRECT;
    protected $routingKey = '';
    public function __construct($data)
    {
        $this->payload = $data;
    }
}


对IndexController进行修改

<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace App\Controller;

use App\Amqp\Producer\DelayDirectProducer;
use App\Model\HyOrder;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Amqp\Producer;

class IndexController extends AbstractController
{

    public function createOrder(){
        $order = new HyOrder();
        $order_data = [
            'orderCode'=>time(),
            'status'=>1
        ];
        //发布到rabbitmq
        $json = json_encode($order_data);
        $message = new DelayDirectProducer($json);
        $message->setDelayMs(10  * 1000);//定时10s
        $producer = ApplicationContext::getContainer()->get(Producer::class);
        $producer->produce($message);
        //插入数据库
        $order->orderCode = $order_data['orderCode'];
        $order->status = $order_data['status'];
        $order->save();
        return "success";
    }
}


对DelayDirectConsumer进行修改

<?php

declare(strict_types=1);

namespace App\Amqp\Consumer;

use Hyperf\Amqp\Result;
use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Message\ConsumerDelayedMessageTrait;
use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\Amqp\Message\ProducerDelayedMessageTrait;
use PhpAmqpLib\Message\AMQPMessage;
use App\Model\HyOrder;
use Hyperf\Amqp\Message\Type;

/**
 * @Consumer( nums=1)
 */
class DelayDirectConsumer extends ConsumerMessage
{
    use ProducerDelayedMessageTrait;
    use ConsumerDelayedMessageTrait;
    protected $exchange = 'ext.hyperf.delay';
    protected $queue = 'queue.hyperf.delay';
    protected $type = Type::DIRECT; //Type::FANOUT;
    protected $routingKey = '';
    public function consumeMessage($data, AMQPMessage $message): string
    {
        $data = json_decode($data,true);
        var_dump($data);
        if($data['orderCode']){
            $order = new HyOrder();
            //根据条件取消订单
            $order = $order->where("orderCode","=",$data['orderCode'] )->where("status",1)->first();
            if($order){
                $order->status = 9;
                $order->save();
            }
        }
        return Result::ACK;
    }
}

接下来运行代码 订单成功取消

在这里插入图片描述
希望对你有所帮助,感谢观看!

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1. 首先安装 RabbitMQ 扩展,可以使用 PECL 安装: ``` pecl install amqp ``` 2. 创建 RabbitMQ 队列和交换机 在 RabbitMQ 中,我们需要创建一个队列和一个交换机来处理自动取消订单功能。可以使用 RabbitMQ 的管理界面或者命令行工具 `rabbitmqctl` 创建,也可以使用 PHP 的 AMQP 扩展创建。 ```php $connection = new AMQPConnection([ 'host' => 'localhost', 'port' => 5672, 'login' => 'guest', 'password' => 'guest', ]); $connection->connect(); $channel = new AMQPChannel($connection); // 创建交换机 $exchange = new AMQPExchange($channel); $exchange->setName('order_exchange'); $exchange->setType(AMQP_EX_TYPE_DIRECT); $exchange->declare(); // 创建队列 $queue = new AMQPQueue($channel); $queue->setName('order_queue'); $queue->declare(); $queue->bind('order_exchange', 'cancel_order'); ``` 3. 发布订单到 RabbitMQ 队列 在订单创建,我们需要将订单信息发布到 RabbitMQ 队列中,以便后续处理。 ```php $order = [ 'order_id' => 12345, 'create_time' => time(), 'expire_time' => time() + 3600, // 订单过期间 ]; $message = json_encode($order); $exchange->publish($message, 'cancel_order'); ``` 4. 监听 RabbitMQ 队列 使用 RabbitMQ 的 AMQP 扩展,我们可以通过监听队列来实现自动取消订单功能。我们需要创建一个消费者,通过 `consume()` 方法监听队列。 ```php $consumer = new AMQPConsumer($channel, $queue); while (true) { $consumer->consume(function ($envelope, $queue) { $message = $envelope->getBody(); $order = json_decode($message, true); if (time() > $order['expire_time']) { // 取消订单 cancelOrder($order['order_id']); } $queue->ack($envelope->getDeliveryTag()); }); } ``` 在消费者回调函数中,我们可以获取订单信息,判断订单是否过期,如果过期就取消订单取消订单的具体实现可以根据业务需求进行编写。 完整的代码示例: ```php $connection = new AMQPConnection([ 'host' => 'localhost', 'port' => 5672, 'login' => 'guest', 'password' => 'guest', ]); $connection->connect(); $channel = new AMQPChannel($connection); // 创建交换机 $exchange = new AMQPExchange($channel); $exchange->setName('order_exchange'); $exchange->setType(AMQP_EX_TYPE_DIRECT); $exchange->declare(); // 创建队列 $queue = new AMQPQueue($channel); $queue->setName('order_queue'); $queue->declare(); $queue->bind('order_exchange', 'cancel_order'); // 发布订单到队列 $order = [ 'order_id' => 12345, 'create_time' => time(), 'expire_time' => time() + 3600, // 订单过期间 ]; $message = json_encode($order); $exchange->publish($message, 'cancel_order'); // 监听队列 $consumer = new AMQPConsumer($channel, $queue); while (true) { $consumer->consume(function ($envelope, $queue) { $message = $envelope->getBody(); $order = json_decode($message, true); if (time() > $order['expire_time']) { // 取消订单 cancelOrder($order['order_id']); } $queue->ack($envelope->getDeliveryTag()); }); } function cancelOrder($orderId) { // 实现取消订单的业务逻辑 } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值