PHP电商订单自动确认收货复述队列

  

一、场景

之前做的电商平台,用户在收到货之后,大部分都不会主动的点击确认收的货,导致给商家结款的时候,商家各种投诉,于是就根据需求,要做一个订单在发货之后的x天自动确认收货。所谓的订单自动确认收的货,就是在在特定的时间,执行一条更新语句,改变订单的状态。

二、思路

最笨重的做法,通过linux后台定时任务,查询符合条件的订单,然后更新。最理想情况下,如果每分钟都有需要更新的订的单,这种方式也还行。奈何平台太小,以及卖家发货时间大部分也是密集的,不会分散在24小时的每分钟,那么,定时任务的话,查询过多,不适合。这里可以先把将要自动确认收货的订单信息存储到其他介质上,比如复述,memcache, rabbitmq,然后执行的脚本从前面的介质获取到订单信息来判断,这里可以大大的减少数据库的查询压力。

<编辑>复述队列的生产者

对此,我们选择每天在凌晨两点的时候,通过linux的定时任务把即将要确认收货的订单信息查询出来,然后存储在复述上,复述,上我们选择的队列,队列处理的特点就是先进先出,前面的数据在查询订单时,通过发货时间排序,所以最先出队列的肯定是距离规定的自动收货时间最近的订单。代码如下

$ successCount=0;   美元failCount=0;   screen_time美元=3600 * 24 * 9;//设置筛选天数   $ data=https://www.yisu.com/zixun/array ();   $ now_time=时间();//查询符合要求的数据   $ sql=把≡駃d, send_time deliver_time从‘秩序’is_send=1 is_del=0和is_cancel=0 is_token=0和send_time> 0和send_time + {$ screen_time} & lt;now_time美元   order by send_time asc”;   res=反对美元→查询($ sql);//当队列还有数据时将数据记录并清除   而(复述→美元LLEN (auto_recevice_order)) {   $ txt=爸葱惺奔?“。日期(Y-m-d H:我:年代”)。”,信息:“。美元复述→RPOP (“auto_recevice_order”);   写入”。/autoToken fail_log.txt’, $ txt。\ r \ n”.PHP_EOL, FILE_APPEND);   美元failCount + +;   }//重新填充数据进队列   而(行=res→美元fetch_assoc ()) {   美元successCount + +;   复述→美元LPUSH (auto_recevice_order, json_encode(第一行)美元);   }   反对美元→close ();   成功=美元日期(Y-m-d H:我:年代”)。”:[推送成功):本次成功推送数据:“successCount美元。”条,记录上次处理失败数据:“failCount美元。“条\ r \ n”;   写入”。/success_log.txt’,美元成功。\ r \ n .PHP_EOL, FILE_APPEND);

<编辑>复述队列的消费者

队列的消费者没有通过linux的定时任务去做,用linux的屏幕+ php cli模式执行php脚本,消费者只需要不断的从队列中读取订单信息,然后判断订单信息中的发货时间,如果达到自动收货的要求,就执行更新语句。同时如果没有达到收货的时间,而且与收货时间间距比较大的时候,可以让php脚本休眠睡一定的时间数,这个时间数自己调节设计,获取出来的未达到时间要求的订单,需要重新推送到复述队列中去,而且还是队列的顶端。以便下次获取。代码如下:

 set_time=3600 * 24 * 10美元;//设置几天后自动收的货
  而(真){
  如果我($ % 30==0){
  usleep(10);//防止而循环使CPU使用率过高
  }
  如果(复述→美元LLEN (auto_recevice_order)) {
  (data=https://www.yisu.com/zixun/json_decode美元复述-> RPOP (' auto_recevice_order '));
  id=(int)数据→美元id;//将数据转化为×××
  deliver_time=(int)数据→美元deliver_time;//将数据转化为×××
  res1=它美元=false;
  $ now_time=时间();
  如果((deliver_time + set_time美元)& lt; now_time美元){
  sql1="美元更新“秩序”设置“is_token '=' 1 ', ' token_time=$ now_time id=$ id和is_send=1 is_del=0和is_cancel=0 is_token=0和send_time + {$ set_time} & lt;美元now_time”;
  res1=反对美元→查询(sql1美元);//更新数据
  (行=mysqli_affected_rows美元con);
  如果美元(行){
  $ ip=$ this→getIp ();
  美元sql2="插入“order_log”(‘order_id’,‘log_msg’,‘log_ip’,‘log_role’,‘log_user’,‘log_order_state’,‘log_time’)值($ id的系统自动收货”,“美元ip”,“系统”,“服务器”、“收货”,now_time美元)”;//写入订单日志
  它=反对美元→查询(sql2美元);//添加日志数据
  }
  }
  if ($ res1==false){//将没达到条件的数据重新插入队列中
  复述→美元RPUSH (auto_recevice_order, json_encode(数组(“id”=祝辞$ id ' deliver_time '=祝辞deliver_time美元)));
  }
  }
  美元我+ +;
  }

PHP电商订单自动确认收货复述队列