如何使用php、html及消息队列实现订单超时自动关闭订单

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用php、html及消息队列实现订单超时自动关闭订单相关的知识,希望对你有一定的参考价值。

我有这样的一个需求,用户生成一个订单后30分钟自动将订单关闭。
php+html做的,现在想用消息队列实现异步的回调,然后改变订单的状态

各位大神,不需要具体的代码,给我点消息队列的使用方式或者思路就可以了。

参考技术A

    从php脚本方面解决的话,那就是每分钟用ajax请求一次php脚本,检查订单状态和当前时间,30分钟后检查到订单无异,测php更新订单到关闭状态,这个地方需要用到setTimeout了,循环执行请求,但是缺点是页面必能关闭,关闭了js就不执行,所以这个方法不太可取,30分钟时间太长,不可能不进行其他页面行为。

    使用mysql 定时计划任务(推荐你使用),语法体

create event myevent
on schedule at current_timestamp + interval 1 hour (周期或者时间点)
do
update myschema.mytable set mycol = mycol + 1;     (执行的sql

详细使用可以参考:https://segmentfault.com/a/1190000005142597,很清楚

参考技术B 你这个问题提的太含糊;不太清楚你的消息队列是怎么产生的??和订单之间有什么联系???要达到怎么样的业务处理流程??

rabbitmq延迟任务的处理

场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时。

场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单。

最近的一个项目遇到了这种情况,如果运单30分钟还没有被接单,则状态自动变为已取消。实现延迟消息原理如下,借用一张图:

技术分享

 

php代码如下:

/**
 * 死信
 * 创建交换机1、交换机2、队列1、队列2
 * 交换机1绑定队列1、交换机2绑定队列2
 * 其中交换机1为死信交换机,队列1处理消息的ttl,队列1没有消费者
 *
 * 由于队列1没有消费者,所以它里面的消息过期后会变成死信,再定义规则,让死信进入交换机2,交换机2再把消息路由到队列2
 * 我们的客户端只需要消费队列2即可
 * 
 * 需要确保业务上每个任务的延迟时间是一致的。如果遇到不同的任务类型需要不同的延时的话,需要为每一种不同延迟时间的消息建立单独的消息队列。
 */
public function actionDeadletter(){
    $connection = new AMQPStreamConnection($this->host, $this->port, $this->user, $this->pass, $this->vhost);
    $channel = $connection->channel();
    
    // 死信交换机和队列的设置
    $channel->exchange_declare(‘dead_exchange‘, ‘direct‘, false, true, false);
    $channel->queue_declare(‘queue1‘, false, true, false, false, false, [
            ‘x-dead-letter-exchange‘ => [‘S‘, ‘normal_exchange‘], // 死信被转发到哪个交换机
            ‘x-dead-letter-routing-key‘ => [‘S‘, ‘normal_routingkey‘] // 死信路由
    ]);
    $channel->queue_bind(‘queue1‘, ‘dead_exchange‘, ‘dead_routingkey‘);
    
    // 正常交换机和队列的设置
    $channel->exchange_declare(‘normal_exchange‘, ‘direct‘, false, true, false);
    $channel->queue_declare(‘queue2‘, false, true, false, false, false);
    $channel->queue_bind(‘queue2‘, ‘normal_exchange‘, ‘normal_routingkey‘);
    
    $msg = new AMQPMessage(‘hello world‘, [
            ‘delivery_mode‘ => 2,
            ‘expiration‘ => 10*1000 //毫秒
    ]);
    
    $channel->basic_publish($msg, ‘dead_exchange‘, ‘dead_routingkey‘);
    
    echo " [x] Sent ‘Hello World!‘\\n";
    $channel->close();
    $connection->close();
}

 运行程序,打开rabbitmq的web管理界面,可以看到消息先进入队列1,当消息过期后会自动进入队列2

参考:https://stackoverflow.com/questions/21942063/how-to-delay-php-amqplib

参考:http://www.cnblogs.com/haoxinyue/p/6613706.html

以上是关于如何使用php、html及消息队列实现订单超时自动关闭订单的主要内容,如果未能解决你的问题,请参考以下文章

基于消息队列(RabbitMQ)实现延迟任务

PHP 框架 Hyperf 实现处理超时未支付订单和延时队列

PHP 框架 Hyperf 实现处理超时未支付订单和延时队列

基于消息队列(RabbitMQ)实现延迟任务

PHP消息队列实现及应用

rabbitmq延迟任务的处理