PHP 使用redis实现秒杀

Posted Sper丶XO

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP 使用redis实现秒杀相关的知识,希望对你有一定的参考价值。

使用redis队列,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,推荐使用(mysql事务在高并发下性能下降很厉害,文件锁的方式也是)

 

先将商品库存如队列

 

[php] view plain copy
 
  1. <?php  
  2. $store=1000;  
  3. $redis=new Redis();  
  4. $result=$redis->connect(‘127.0.0.1‘,6379);  
  5. $res=$redis->llen(‘goods_store‘);  
  6. echo $res;  
  7. $count=$store-$res;  
  8. for($i=0;$i<$count;$i++){  
  9.     $redis->lpush(‘goods_store‘,1);  
  10. }  
  11. echo $redis->llen(‘goods_store‘);  
  12. ?>  


抢购、描述逻辑

 

 

[php] view plain copy
 
    1. <?php  
    2. $conn=mysql_connect("localhost","big","123456");    
    3. if(!$conn){    
    4.     echo "connect failed";    
    5.     exit;    
    6. }   
    7. mysql_select_db("big",$conn);   
    8. mysql_query("set names utf8");  
    9.   
    10. $price=10;  
    11. $user_id=1;  
    12. $goods_id=1;  
    13. $sku_id=11;  
    14. $number=1;  
    15.   
    16. //生成唯一订单号  
    17. function build_order_no(){  
    18.     return date(‘ymd‘).substr(implode(NULL, array_map(‘ord‘, str_split(substr(uniqid(), 7, 13), 1))), 0, 8);  
    19. }  
    20. //记录日志  
    21. function insertLog($event,$type=0){  
    22.     global $conn;  
    23.     $sql="insert into ih_log(event,type)   
    24.     values(‘$event‘,‘$type‘)";    
    25.     mysql_query($sql,$conn);    
    26. }  
    27.   
    28. //模拟下单操作  
    29. //下单前判断redis队列库存量  
    30. $redis=new Redis();  
    31. $result=$redis->connect(‘127.0.0.1‘,6379);  
    32. $count=$redis->lpop(‘goods_store‘);  
    33. if(!$count){  
    34.     insertLog(‘error:no store redis‘);  
    35.     return;  
    36. }  
    37.   
    38. //生成订单    
    39. $order_sn=build_order_no();  
    40. $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)   
    41. values(‘$order_sn‘,‘$user_id‘,‘$goods_id‘,‘$sku_id‘,‘$price‘)";    
    42. $order_rs=mysql_query($sql,$conn);   
    43.   
    44. //库存减少  
    45. $sql="update ih_store set number=number-{$number} where sku_id=‘$sku_id‘";  
    46. $store_rs=mysql_query($sql,$conn);    
    47. if(mysql_affected_rows()){    
    48.     insertLog(‘库存减少成功‘);  
    49. }else{    
    50.     insertLog(‘库存减少失败‘);  
    51. }   
        1. --  
        2. -- 数据库: `big`  
        3. --  
        4.   
        5. -- --------------------------------------------------------  
        6.   
        7. --  
        8. -- 表的结构 `ih_goods`  
        9. --  
        10.   
        11.   
        12. CREATE TABLE IF NOT EXISTS `ih_goods` (  
        13.   `goods_id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
        14.   `cat_id` int(11) NOT NULL,  
        15.   `goods_name` varchar(255) NOT NULL,  
        16.   PRIMARY KEY (`goods_id`)  
        17. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;  
        18.   
        19.   
        20. --  
        21. -- 转存表中的数据 `ih_goods`  
        22. --  
        23.   
        24.   
        25. INSERT INTO `ih_goods` (`goods_id`, `cat_id`, `goods_name`) VALUES  
        26. (1, 0, ‘小米手机‘);  
        27.   
        28. -- --------------------------------------------------------  
        29.   
        30. --  
        31. -- 表的结构 `ih_log`  
        32. --  
        33.   
        34. CREATE TABLE IF NOT EXISTS `ih_log` (  
        35.   `id` int(11) NOT NULL AUTO_INCREMENT,  
        36.   `event` varchar(255) NOT NULL,  
        37.   `type` tinyint(4) NOT NULL DEFAULT ‘0‘,  
        38.   `addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
        39.   PRIMARY KEY (`id`)  
        40. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;  
        41.   
        42. --  
        43. -- 转存表中的数据 `ih_log`  
        44. --  
        45.   
        46.   
        47. -- --------------------------------------------------------  
        48.   
        49. --  
        50. -- 表的结构 `ih_order`  
        51. --  
        52.   
        53. CREATE TABLE IF NOT EXISTS `ih_order` (  
        54.   `id` int(11) NOT NULL AUTO_INCREMENT,  
        55.   `order_sn` char(32) NOT NULL,  
        56.   `user_id` int(11) NOT NULL,  
        57.   `status` int(11) NOT NULL DEFAULT ‘0‘,  
        58.   `goods_id` int(11) NOT NULL DEFAULT ‘0‘,  
        59.   `sku_id` int(11) NOT NULL DEFAULT ‘0‘,  
        60.   `price` float NOT NULL,  
        61.   `addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
        62.   PRIMARY KEY (`id`)  
        63. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=‘订单表‘ AUTO_INCREMENT=1 ;  
        64.   
        65. --  
        66. -- 转存表中的数据 `ih_order`  
        67. --  
        68.   
        69.   
        70. -- --------------------------------------------------------  
        71.   
        72. --  
        73. -- 表的结构 `ih_store`  
        74. --  
        75.   
        76. CREATE TABLE IF NOT EXISTS `ih_store` (  
        77.   `id` int(11) NOT NULL AUTO_INCREMENT,  
        78.   `goods_id` int(11) NOT NULL,  
        79.   `sku_id` int(10) unsigned NOT NULL DEFAULT ‘0‘,  
        80.   `number` int(10) NOT NULL DEFAULT ‘0‘,  
        81.   `freez` int(11) NOT NULL DEFAULT ‘0‘ COMMENT ‘虚拟库存‘,  
        82.   PRIMARY KEY (`id`)  
        83. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT=‘库存‘ AUTO_INCREMENT=2 ;  
        84.   
        85. --  
        86. -- 转存表中的数据 `ih_store`  
        87. --  
        88.   
        89. INSERT INTO `ih_store` (`id`, `goods_id`, `sku_id`, `number`, `freez`) VALUES  
        90. (1, 1, 11, 500, 0);  

以上是关于PHP 使用redis实现秒杀的主要内容,如果未能解决你的问题,请参考以下文章

php结合redis实现高并发下的抢购秒杀功能

php+redis实现简单秒杀抢购功能

thinkphp+redis实现秒杀功能

php结合redis实现高并发下的抢购秒杀功能

php结合redis实现高并发下的抢购秒杀功能

php结合redis实现高并发下的抢购秒杀功能