php如何实现电商订单自动确认收货?今天小编就为大家带来php使用redis队列实现电商订单自动确认收货的知识。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望对大家有所帮助。
一、场景
之前做的电商平台,用户在收到货之后,大部分都不会主动的点击确认收货,导致给商家结款的时候,商家各种投诉,于是就根据需求,要做一个订单在发货之后的x天自动确认收货。所谓的订单自动确认收货,就是在在特定的时间,执行一条update语句,改变订单的状态。
二、思路
最笨重的做法,通过linux后台定时任务,查询符合条件的订单,然后update。最理想情况下,如果每分钟都有需要update的订单,这种方式也还行。奈何平台太小,以及卖家发货时间大部分也是密集的,不会分散在24小时的每分钟。那么,定时任务的话,查询过多,不适合。这里可以先把将要自动确认收货的订单信息存储到其他介质上,比如redis,memcache,rabbitmq,然后执行的脚本从前面的介质获取到订单信息来判断,这里可以大大的减少数据库的查询压力。
立即学习“PHP免费学习笔记(深入)”;
redis队列的生产者
对此,我们选择每天在凌晨两点的时候,通过linux的定时任务把即将要确认收货的订单信息查询出来,然后存储在redis上,redis上我们选择的队列,队列处理的特点就是先进先出,前面的数据在查询订单时,通过发货时间排序,所以最先出队列的肯定是距离规定的自动收货时间最近的订单。代码如下
$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} query($sql); //当队列还有数据时将数据记录并清除 while($redis->LLEN('auto_recevice_order')){ $txt = '执行时间:'.date('Y-m-d H:i:s').',信息:'.$redis->RPOP('auto_recevice_order'); file_put_contents('./autoToken/fail_log.txt',$txt." ".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."条 "; file_put_contents('./success_log.txt',$success." ".PHP_EOL,FILE_APPEND);登录后复制
redis队列的消费者
队列的消费者没有通过linux的定时任务去做,用linux的screen+php cli模式执行php脚本,消费者只需要不断的从队列中读取订单信息,然后判断订单信息中的发货时间,如果达到自动收货的要求,就执行update语句。同时如果没有达到收货的时间,而且与收货时间间距比较大的时候,可以让php脚本休眠sleep一定的时间数,这个时间数自己调节设计,获取出来的未达到时间要求的订单,需要重新推送到redis队列中去,而且还是队列的顶端。以便下次获取。代码如下:
$set_time = 3600*24*10;//设置几天后自动收货 while(true){ if($i0==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)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守护进程。具体用法可自行百度.同样脚本里面最好有必须的日志记录。
三、思考
随着业务的增长,在队列中同一秒内,存在的多个需要处理的订单,而一次只能从队列中取出一个相关订单信息的时候,可以采用一个生产者多个消费者的模式,这种情况下,可以用到锁机制,保证一条消息只能到达一个消费者。当redis数据达到一定的量之后,也可以适当的调整生产者的执行频率和对应的条件。
相关推荐:
详解php7如何实现MongoDB模糊查询
详解PHP如何实现简易的搜索框自动提示功能
php脚本中的$argv和$argc配置方法
以上就是详解PHP使用redis队列实现电商订单自动确认收货的详细内容,更多请关注慧达安全导航其它相关文章!
免责 声明
1、本网站名称:慧达安全导航
2、本站永久网址:https//www.huida178.com/
3、本站所有资源来源于网友投稿和高价购买,所有资源仅对编程人员及源代码爱好者开放下载做参考和研究及学习,本站不提供任何技术服务!
4、本站所有资源的属示图片和信息不代表本站的立场!本站只是储蓄平台及搬运
5、下载者禁止在服务器和虚拟机下进行搭建运营,本站所有资源不支持联网运行!只允许调试,参考和研究!!!!
6、未经原版权作者许可禁止用于任何商业环境,任何人不得擅作它用,下载者不得用于违反国家法律,否则发生的一切法律后果自行承担!
7、为尊重作者版权,请在下载24小时内删除!请购买原版授权作品,支持你喜欢的作者,谢谢!
8.若资源侵犯了您的合法权益,请持 您的版权证书和相关原作品信息来信通知我们!QQ:1247526623我们会及时删除,给您带来的不便,我们深表歉意!
9、如下载链接失效、广告或者压缩包问题请联系站长处理
10、如果你也有好源码或者教程,可以发布到网站,分享有金币奖励和额外收入!
11、本站资源售价只是赞助,收取费用仅维持本站的日常运营所需
12、因源码具有可复制性,一经赞助,不得以任何形式退款。
13、本文内容由网友自发贡献和站长收集,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系1247526623@qq.com
转载请注明出处: 慧达安全导航 » 详解PHP使用redis队列实现电商订单自动确认收货
发表评论 取消回复