PHP电子商务商品订单自动确认收货的实现(redis队列)
下面小编就为大家带来一篇PHP电子商务商品订单自动确认收货的实现(redis队列)。
小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
电商平台,用户在收到货之后,如果用户没有点击确认收货,我们一般做一个订单在发货之后的x天自动确认收货。
订单自动确认收货,就是在在特定的时间,执行一条update语句,改变订单的状态。
实现方法
一种是通过linux后台定时任务,查询符合条件的订单,然后update。最理想情况下,如果每分钟都有需要update的订单,这种方式也还行。
另一种是我们先把将要自动确认收货的订单信息存储到其他介质上,比如redis,memcache,rabbitmq,然后执行的脚本从前面的介质获取到订单信息来判断,这就大大的减少数据库的查询压力。
redis队列的生产者
我们选择每天在凌晨的时候,通过linux的定时任务把即将要确认收货的订单信息查询出来,然后存储在redis上,redis上我们选择的队列,队列处理的特点就是先进先出,
前面的数据在查询订单时,通过发货时间排序,所以最先出队列的肯定是距离规定的自动收货时间最近的订单。php代码如下
$successCount = 0;
$failCount = 0;
$screen_time = 3600 * 24 * 9;//设置筛选天数
$data = array();
$now_time = time();
//查询符合要求的数据
$sql = "select id,send_time as deliver_time from `order`
where is_send=1 and is_del=0 and is_cancel=0 and is_token=0 and send_time>0
and send_time + {$screen_time} < $now_time order by send_time asc";
$res = $con->query($sql);
//当队列还有数据时将数据记录并清除
while ($redis->LLEN('auto_recevice_order')) {
$txt = '执行时间:' . date('Y-m-d H:i:s') . ',信息:' . $redis->RPOP('auto_recevice_order');
file_put_contents('./fail_log.txt', $txt . "/r/n" . PHP_EOL, FILE_APPEND);
$failCount++;
}
//重新填充数据进队列
while ($row = $res->fetch_assoc()) {
$successCount++;
$redis->LPUSH('auto_recevice_order', json_encode($row1));
}
$con->close();
$success = date('Y-m-d H:i:s') . ':[推送成功]:本次成功推送数据:' .
$successCount . '条;记录上次处理失败数据:' . $failCount . "条/r/n";
file_put_contents('./success_log.txt', $success . "/r/n" . PHP_EOL, FILE_APPEND);
redis队列的消费者
队列的消费者没有使用linux的定时任务,用linux的screen+php cli模式执行php脚本,消费者需要不断的从队列中读取订单信息,然后判断订单信息中的发货时间,如果达到自动收货的要求,就执行update语句。
同时如果没有达到收货的时间,而且与收货时间间距比较大的时候,可以让php脚本休眠sleep一定的时间数,获取出来的未达到时间要求的订单,需要重新推送到redis队列中去,而且还是队列的顶端。php代码如下:
$set_time = 3600 * 24 * 10;//设置几天后自动收货
while (true) {
if ($i % 30 == 0) {
usleep(10);//防止while 循环使CPU使用率过高
}
if ($redis->LLEN('auto_recevice_order')) {
$data = json_decode($redis->RPOP('auto_recevice_order'));
$id = (int)$data->id;//将数据转化为整形
$deliver_time = (int)$data->deliver_time;//将数据转化为整形
$res1 = $res2 = false;
$now_time = time();
if (($deliver_time + $set_time) < $now_time) {
$sql1 = "update `order` set `is_token`='1',`token_time` = $now_time where id=$id
and is_send=1 and is_del=0 and is_cancel=0 and is_token=0 and send_time + {$set_time} < $now_time";
$res1 = $con->query($sql1);//更新数据
$rows = mysqli_affected_rows($con);
if ($rows) {
$ip = $this->getIp();
$sql2 = "insert into `order_log`(`order_id`,`log_msg`,`log_ip`,`log_role`,`log_user`,
`log_order_state`,`log_time`) VALUES ($id,'系统自动收货','$ip','系统','服务器','收货',$now_time)";//写入订单日志
$res2 = $con->query($sql2);//添加日志数据
}
}
if ($res1 == false) {
//将没达到条件的数据重新插入队列中
$redis->RPUSH('auto_recevice_order', json_encode(array('id' => $id, 'deliver_time' => $deliver_time)));
}
}
$i++;
}
这里执行php脚本,需要用到linux的screen或者supervisor、nohup守护进程。脚本里面最好有日志记录。
以上这篇PHP电子商务商品订单自动确认收货的实现(redis队列)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本站。


相关推荐
深度学习 -- 损失函数
深度残差网络(Deep Residual Networks (ResNets))
深度学习 -- 激活函数
神经网络训练 -- 调整学习速率
生成对抗网络(GAN)改进与发展
生成对抗网络(GAN)优点与缺点
生成对抗网络(GAN)的训练
生成对抗网络(GAN)基本原理
生成模型与判别模型