Php + redis to achieve the mall second kill function, redis mall
I haven't been sorting out my articles for a long time. I am free to write an article to record the php + redis flash sales function for the mall.
1. Install redis and install the corresponding redis Extension Based on your php version (this step is briefly described)
1. Install php_igbinary.dll and php_redis.dll extension. Pay attention to your php version.
Extension = php_igbinary.dll added to the 1.2.php.ini file; extension = php_redis.dll extension
OK. The first step is to build the redis environment. See phpinfo.
2. Use redis in the project
2. 1. Configure the following redis parameters in the first step. The default port for redis installation is 6379:
<? Php/* Database Configuration */return array ('data _ cache_prefix' => 'redis _ ', // cache prefix 'data _ CACHE_TYPE' => 'redis ', // The default dynamic cache is Redis 'data _ CACHE_TIMEOUT '=> false, 'redis _ RW_SEPARATE' => true, // enable 'redis _ host' => '127 for Redis read/write splitting true. 0.0.1 ', // redis Server ip address, separated by commas. When read/write splitting is enabled, the first server is responsible for writing, and the other [random] server is responsible for reading; 'redis _ port' => '123', // PORT number 'redis _ timeout' => '123', // TIMEOUT time 'redis _ PERSISTENT '=> false, // whether persistent connection is false = short connection 'redis _ auth' => '', // AUTH password);?>
2. Use redis in actual functions:
/*** Redis connection ** @ access private * @ return resource * @ author bieanju */private function connectRedis () {$ redis = new \ Redis (); $ redis-> connect (C ("REDIS_HOST"), C ("REDIS_PORT"); return $ redis ;}
2.3. The core problem of the second kill is that the purchase will not go beyond the inventory in the case of high concurrency. This is the key to processing. So the idea is to first generate some basic data in the second kill class:
// The public function _ initialize () {parent: _ initialize (); $ goods_id = I ("goods_id", '0 ', 'intval'); if ($ goods_id) {$ this-> goods_id = $ goods_id; $ this-> user_queue_key = "goods _". $ goods_id. "_ user"; // user information of the current product queue $ this-> goods_number_key = "goods ". $ goods_id; // The inventory queue of the current item} $ this-> user_id = $ this-> user_id? $ This-> user_id: $ _ SESSION ['uid'];}
2.4. The second step is the key. before entering the product details page, the user first queues the inventory of the current product and saves it to redis as follows:
/*** Run the "@ access public * @ author bieanju */public function _ before_detail ()" command before accessing the product () {$ where ['goods _ id'] = $ this-> goods_id; $ where ['start _ time'] = array ("lt", time ()); $ where ['end _ time'] = array ("gt", time (); $ goods = M ("goods")-> where ($ where) -> field ('goods _ num, start_time, end_time ')-> find ();! $ Goods & $ this-> error ("the current seckilling has ended! "); If ($ goods ['goods _ num']> $ goods ['order _ num']) {$ redis = $ this-> connectRedis (); $ getUserRedis = $ redis-> hGetAll ("{$ this-> user_queue_key}"); $ gnRedis = $ redis-> llen ("{$ this-> goods_number_key }"); /* if no member comes in to the queue */if (! Count ($ getUserRedis )&&! $ GnRedis) {for ($ I = 0; $ I <$ goods ['goods _ num']; $ I ++) {$ redis-> lpush ("{$ this-> goods_number_key}", 1 );}} $ resetRedis = $ redis-> llen ("{$ this-> goods_number_key}"); if (! $ ResetRedis) {$ this-> error ("the system is busy. Please buy it later! ") ;}} Else {$ this-> error (" the current product has been killed in seconds! ");}}
The next step is to use ajax for asynchronous processing. the user clicks the Buy button to enter the purchase queue for Qualified Data (if the current user is not in the queue of the current product user, the user enters the queue and POPs an inventory queue, if it is thrown ,):
/*** Pre-sales: whether the current member enters the queue * @ access public * @ author bieanju */public function goods_number_queue (){! $ This-> user_id & $ this-> ajaxReturn (array ("status" => "-1", "msg" => "Log on first ")); $ model = M ("flash_sale"); $ where ['goods _ id'] = $ this-> goods_id; $ goods_info = $ model-> where ($ where) -> find ();! $ Goods_info & $ this-> error ("sorry, the current product does not exist or is not available! ");/* Redis queue */$ redis = $ this-> connectRedis (); /* enter the queue */$ goods_number_key = $ redis-> llen ("{$ this-> goods_number_key}"); if (! $ Redis-> hGet ("{$ this-> user_queue_key}", $ this-> user_id )) {$ goods_number_key = $ redis-> lpop ("{$ this-> goods_number_key}") ;}if ($ goods_number_key) {// determine whether the user is already in the queue if (! $ Redis-> hGet ("{$ this-> user_queue_key}", $ this-> user_id )) {// Insert the user information $ userinfo = array ("user_id" = >$ this-> user_id, "create_time" => time ()); $ redis-> hSet ("{$ this-> user_queue_key}", $ this-> user_id, serialize ($ userinfo )); $ this-> ajaxReturn (array ("status" => "1");} else {$ modelCart = M ("cart "); $ condition ['user _ id'] = $ this-> user_id; $ condition ['goods _ id'] = $ this-> goods_id; $ condition ['prom _ typ E '] = 1; $ cartlist = $ modelCart-> where ($ condition)-> count (); if ($ cartlist> 0) {$ this-> ajaxReturn (array ("status" => "2 "));} else {$ this-> ajaxReturn (array ("status" => "1 "));}}} else {$ this-> ajaxReturn (array ("status" => "-1", "msg" => "the system is busy. Please try again! "));}}
Add a debug function to delete the specified queue value:
Public function clearRedis () {set_time_limit (0); $ redis = $ this-> connectRedis (); // $ Rd = $ redis-> del ("{$ this-> user_queue_key}"); $ Rd = $ redis-> hDel ("goods49 ", 'User id'); $ a = $ redis-> hGet ("goods_49_user", 'user id'); if (! $ A) {dump ($ a);} if ($ Rd = 0) {exit ("The Redis queue has been released! ");}}
At this point, the core of the second kill is basically complete, and the details still need to be improved by yourself, such as the processing of the shopping cart and the processing of orders, run the program and use apache's AB to perform a simple simulated concurrency test as follows:
Okay. Now all are completed, as shown in the following figure:
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.