How PHP handles high concurrent requests for snapping-like features

Source: Internet
Author: User
Tags php framework yii
Two problems of easy parameter under high concurrent request

1. Data error, resulting in product oversold.

2. Frequent database operations, resulting in degraded performance.

This article mainly and everybody introduced in detail the PHP processing snapping up the function of high concurrent requests, with a certain reference value, interested in small partners can refer to, hope to help everyone.

Test environment

Windows7
apache2.4.9
php5.5.12
PHP Framework yii2.0
Tool Apache Bench (Apache comes with high concurrency request tool).

Common processing methods

From the controller you can see the code idea. Check the product inventory first. If the inventory is greater than 0, the inventory is reduced by 1, while the production order is entered into the snapping data.


General code handling high concurrency public  function Actionnormal () {    //querying inventory    $stock = Goods::find ()->select (' stock ') where ([' goods_id ' =>100001])->asarray ()->one ();    Determine if the item is still in stock    if ($stock [' stock ']>0) {      //inventory minus one      goods::updateallcounters ([' stock ' = ' -1],[' Goods_ Id ' =>100001]);      Production order (additional function, for the moment, random assignment)      $order = $this->build_order ();      Second kill information storage      $model = new highly ();      $model->order_id = $order;      $model->goods_name = ' seconds to kill goods ';      $model->buy_time = Date (' y-m-d h:i:s ', Time ());      $model->mircrotime = Microtime (true);      if ($model->save () ===false) {        echo ' failed to snap! ';      } else{        Echo ' Congratulations, Order <b> '. $order. ' </b> snapping success ';      }    } else{      Echo ' has been sold out! ';    }  }

After the commodity inventory is set to 20, a concurrent request is configured through AB 200.


Ab-n 200-c Http//localhost/highly/normal

The results of the execution found that the inventory turned negative and the goods were oversold.

The reason is relatively simple, under high concurrent requests. Before production orders are reduced, inventory results are prioritized.

optimization One: Modifying the inventory data type

The first method of optimization, starting with the database. Since the results of the query are inaccurate, I will tamper with the inventory reduction. Change the data type of the inventory to unsigned (cannot have negative values).

The code is similar to the above, only in the inventory minus 1 of the place made a judgment. Avoid error.


Public Function Actionnormal () {    //query inventory    $stock = Goods::find ()->select (' Stock ')->where ([' goods_id ' = >100001])->asarray ()->one ();    Determine if the item is still in stock    if ($stock [' stock ']>0) {      //stock minus one      if (goods::updateallcounters ([' stock '] = -1],[' goods_id ' =>100001]) (===false) {        echo "has been sold out!";        return false;      }      Production order (additional function, for the moment, random assignment)      $order = $this->build_order ();      Second kill information storage      $model = new highly ();      $model->order_id = $order;      $model->goods_name = ' seconds to kill goods ';      $model->buy_time = Date (' y-m-d h:i:s ', Time ());      $model->mircrotime = Microtime (true);      if ($model->save () ===false) {        echo ' failed to snap! ';      } else{        Echo ' Congratulations, Order <b> '. $order. ' </b> snapping success ';      }    } else{      Echo ' has been sold out! ';    }  }

This time the same 200 concurrency, the execution results found. The data is correct and there is no oversold situation.
The idea is actually relatively simple. Because the inventory can not be negative, when the inventory equals 0 o'clock, if there are values passed in, it will be an error. The request was terminated.

This optimization method, although avoids the product oversold situation. On the other hand, however, the request will still cause stress on the database. If more than one feature uses this database, it can cause a severe performance degradation.

optimization Two:Redis

The atomicity of a pop using the Redis list type. Do a validation before you manipulate the database. When the product is sold out, it is not allowed to continue the database operation.


Redis List high concurrency test public Function Actionredis () {$redis = \yii:: $app->redis;    $redis->lpush (' mytest ', 1);    $order = $this->build_order ();    echo $order;d ie;    echo $redis->llen (' mytest ');    $reg = $redis->lpop (' mytest '); if (! $reg) {echo "Idiot! have been robbed!      ";    return false;    } $redis->close ();    $model = new highly ();    $model->order_id = $order;    $model->goods_name = ' seconds to kill goods ';    $model->buy_time = Date (' y-m-d h:i:s ', Time ());    $model->mircrotime = Microtime (true); if ($model->save () ===false) {echo ' failed to snap!    '; }else{Echo ' Congratulations, Order <b> '. $order. '    </b> snapping up success ';    }//To Redis Add commodity public Function actioninsertgoods () {$count = Yii:: $app->request->get (' count ', 0);      if (empty ($count)) {echo ' Big Brother, you haven't told me how many items I need on the shelves! ';    return false;    } $redis = \yii:: $app->redis;    for ($i =0; $i < $count; $i + +) {$redis->lpush (' mytest ', 1); } Echo ' successfully added '. $redis->llen (' myTESt '). ' Items.    ';  $redis->close (); }

This code, I wrote two methods. The first method is the code of the second Kill, the second method is to set the number of seconds to kill the product. In order to facilitate the test, I deal with the relatively simple here.

Through testing, the number of orders produced by the database is normal, and no problems occur. It also avoids the problem of requesting the database to cause performance degradation. At the same time, the memory database Redis queries are much faster than MySQL.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.