How does PHP implement e-commerce orders to automatically confirm receipts? Today's small series for everyone to bring PHP using the Redis queue to achieve e-commerce orders to automatically confirm the receipt of knowledge. Small series feel very good, now share to everyone, also for everyone to make a reference. Follow the small part together to see it, hope to help you.
First, the scene
Before the e-commerce platform, the user in the receipt of goods, most of them will not take the initiative to confirm the receipt, resulting in the business of the payment, the merchant various complaints, so according to demand, to do an order after the delivery of X days automatically confirm receipt. The so-called automatic confirmation of receipt of orders, that is, at a specific time, execute an UPDATE statement, change the status of the order.
Second, the idea
The most cumbersome approach, through the Linux Background Timer task, query the eligible orders, and then update. Ideally, this would be fine if there were orders to update every minute. The platform is too small, and most of the seller's delivery time is also dense, not scattered in 24 hours per minute. Then, the timing of the task, the query too much, not suitable. Here you can automatically confirm the receipt of the order information stored on other media, such as REDIS,MEMCACHE,RABBITMQ, and then execute the script from the previous media to obtain the order information to judge, here can greatly reduce the database query pressure.
The producer of the Redis queue
For this, we choose every day at two o'clock in the morning, through the Linux scheduled task to confirm the receipt of the order information, and then stored on the Redis, Redis on the queue we select, the queue processing is the first-in-one, the front of the data in the query order, Ordered by shipping time, so the first out of the queue is definitely the nearest order from the specified automatic receipt time. The code is as follows
$successCount =0; $failCount =0; $screen _time = 3600*24*9;//set filter days $data = Array () ; $now _time = time ();//query conforms to the required data $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 _timeorder by send_time asc "; $res = $co N->query ($sql);//Record data while the queue has data and clear while ($redis->llen (' Auto_recevice_order ')) {$txt = ' execution time: '. Date (' y-m-d h:i: S '). ', Info: '. $redis->rpop (' Auto_recevice_order '); File_put_contents ('./autotoken/fail_log.txt ', $txt. " \ r \ n ". Php_eol,file_append); $failCount + +;} Repopulate the data into the queue while ($row = $res->fetch_assoc ()) {$successCount + +; $redis->lpush (' Auto_recevice_order ', json_ Encode ($row 1));} $con->close (); $success =date (' y-m-d h:i:s '). ': [Push success]: This successful push data: '. $successCount. ', record last processing failed data: '. $failCount. ' Article \ r \ n "; File_put_contents ('./success_log.txt ', $success. " \ r \ n ". Php_eol,file_append);
Customers of Redis queues
Queue of consumers do not through the timing of the Linux task to do, with the Linux screen+php CLI mode to execute PHP script, the consumer only need to continuously read order information from the queue, and then determine the order information in the delivery time, if the requirements of automatic receipt, The UPDATE statement is executed. At the same time, if the receipt is not reached, and with the receipt of the time span is relatively large, you can let the PHP script sleep a certain amount of time, the amount of time to adjust the design, to get out of the time required for the order to be re-pushed to the Redis queue, but also the top of the queue. To get it next time. The code is as follows:
$set _time = 3600*24*10;//set a few days after the automatic receipt while (true) {if ($i%30==0) {usleep (10);//prevents the while loop from excessively high CPU usage}if ($redis->llen (' Auto_recevice_order ') {$data = Json_decode ($redis->rpop (' Auto_recevice_order ')), $id = (int) $data->id;// Convert data to shaping $deliver_time = (int) $data->deliver_time;//convert data to shaping $res1 = $res 2 =false; $now _time = time (); if ($deliver _ time+ $set _time) < $now _time) {$sql 1 = "Update ' order ' set ' is_token ' = ' 1 ', ' token_time ' = $now _time where id= $id and Is_sen D=1 and Is_del=0 and Is_cancel=0 and is_token=0 and Send_time + {$set _time} < $now _time "; $res 1 = $con->query ($sql 1);//Update Data $rows = Mysqli_affected_rows ($con), if ($rows) {$ip = $this->getip (); $sql 2 = " Insert INTO ' order_log ' (' order_id ', ' log_msg ', ' log_ip ', ' log_role ', ' log_user ', ' log_order_state ', ' Log_time ') VALUES ( $id, ' System automatic receipt ', ' $ip ', ' System ', ' server ', ' receipt ', $now _time) ';//write the Order Log $res 2 = $con->query ($sql 2);//Add log Data}} if ($res 1==false) { Reinsert data that is not up to the condition into the queue $redis->rpush (' Auto_recevice_order ', Json_encode (' id ' = ' = ' $id, ' deliver_time '= $deliver _time))); }} $i + +;}
Executing PHP scripts here requires the use of the Linux screen or supervisor, Nohup daemon. The specific use of Baidu can be self-contained in the same script it is best to have the necessary log records.
Third, thinking
As the business grows, in the same second in the queue, there are many orders that need to be processed, and one can only fetch a relevant order information from the queue at a time, the model of multiple consumers may be used, in which case the lock mechanism can be used to ensure that a message can reach only one consumer. When the Redis data reaches a certain amount, it can also adjust the producer's execution frequency and the corresponding condition appropriately.
Related recommendations:
Detailed PHP7 how to implement MongoDB fuzzy query
How to implement Simple automatic search box prompt function in PHP
$ARGV and $ARGC configuration methods in PHP scripts