大家平常在买东西的情况下,在接收货以后,绝大多数都不可能自动的点一下确定收货,造成给店家结算的情况下,店家各种各样举报,因此就按照要求,要做一个订单在送货以后的x天全自动确定收货。所说的订单全自动确定收货,便是在在特殊的時间,实行一条update句子,更改订单的情况。
构思
最沉重的作法,根据linux后台管理计划任务,查看满足条件的订单,随后update。最理想化状况下,假如每分都是有必须update的订单,这类方法也还好。怎奈服务平台过小,及其商家发货时间绝大多数也是聚集的,不容易分散化在24个小时的每分。那麼,计划任务得话,查看太多,不适宜。这儿可以先把即将全自动确定收货的订单信息内容储存到别的物质上,例如redis,memcache,rabbitmq,随后实行的脚本制作从之前的物质获得到订单信息内容来分辨,这儿可以大大降低数据库的查看工作压力。
造成队列
对于此事,大家挑选每日在凌晨三点的情况下,根据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} < $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(./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、nohupxinetd。实际使用方法可自己百度搜索.一样脚本制作里边最好是有一定的日志纪录。
思索
伴随着项目的提高,在队列中同一秒内,存有的好几个必须处置的订单,而一次只有从队列中拿出一个有关订单信息内容的情况下,可以选用一个经营者好几个顾客的方式,这样的事情下,可以使用锁体制,确保一条信息只有抵达一个顾客。当redis数据做到一定的量以后,还可以适度的调节经营者的实行頻率和相对应的标准.
关心本简书号,大量有关python、Java干货知识、方法等你免费学~
Copyright © All rights reserved | Colorlib 沪ICP备2021024381号-16
扫码咨询与免费使用
申请免费使用