方案一: crontab 定时任务, 检测未支付订单是否超时, 超时后修改状态


方案二: 使用redis监听过期key  

需要先先修改redis.conf配置, 后重启redis

notify-keyspace-events Ex


我们测试 指定判断 前缀为test_order_的key

订阅者代码:

<?php 

// 初始化redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('***');


$redis->setOption(Redis::OPT_SERIALIZER, -1);
// 先在redis配置文件中设置 notify-keyspace-events Ex
// 监听所以过期的key
$redis->psubscribe(["__keyevent@0__:expired"], 'callback');

// 回调函数,这里写处理逻辑
function callback($redis, $pattern, $channel, $message)
{
    // callback为订阅事件后的回调函数,这里写业务处理逻辑
    // echo "接收到来自频道 {$channel} 的消息: {$message}";
    if(strpos($message, 'test_order_') !== false){
        $orderno = substr($message, 11);
        echo "订单 {$orderno} 已过期".PHP_EOL;
    }
}


发布者代码: 

<?php

// 初始化redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('****');


// 模拟订单未支付超时
$orderno = time().rand(10000,99999);
$limit = 5;   // 测试, 设置5秒超时
$redis->setex('test_order_'.$orderno, $limit, 1);   // 设置redis过期时间, 只用到redis的 key


测试效果

订单超时、活动过期解决方案redis_订单超时