1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > PHP和Redis实现在高并发下抢购及秒杀

PHP和Redis实现在高并发下抢购及秒杀

时间:2019-09-29 21:48:05

相关推荐

PHP和Redis实现在高并发下抢购及秒杀

后端开发|php教程

Redis,php,抢购

后端开发-php教程

本文主要和大家分享PHP和Redis实现在高并发下抢购及秒杀,抢购、秒杀是平常很常见的场景,面试的时候面试官也经常会问到,比如问你淘宝中的抢购秒杀是怎么实现的等等,希望能帮助到大家

html tree 源码,vscode代码调用,ubuntu lxslt,tomcat 定时插件,sqlite中英文排序,z-blog投稿插件,前端模板网站开发框架免费,清除厨房厕所爬虫的办法,php http请求头,乳山谷歌seo,网站程序开发公司,易语言 取网页标题,互联网平台模板下载软件lzw

抢购、秒杀实现很简单,但是有些问题需要解决,主要针对两个问题:

微信直播源码搭建,ubuntu安装erp系统,tomcat7 配置虚拟,爬虫软件创业,php视频提取flash地址,seo seunglzw

A、高并发对数据库产生的压力

B、竞争状态下如何解决库存的正确减少(”超卖”问题)

推广注册赚钱源码完美运营版,如何降低ubuntu版本,tomcat一堆英文的页面,golang爬虫异步加载,php突然不能运行什么都没改,seo分析行业lzw

第一个问题,对于PHP来说很简单,用缓存技术就可以缓解数据库压力,比如memcache,redis等缓存技术。

第二个问题就比较复杂点:

常规写法:

查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数。

0){//高并发下会导致超卖$order_sn=build_order_no();//生成订单$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)values($order_sn,$user_id,$goods_id,$sku_id,$price)";$order_rs=mysql_query($sql,$conn);//库存减少$sql="update ih_store set number=number-{$number} where sku_id=$sku_id\";$store_rs=mysql_query($sql,$conn);if(mysql_affected_rows()){insertLog(库存减少成功);}else{insertLog(库存减少失败);}}else{insertLog(库存不够);}出现这种情况怎么办呢?来看几种优化方法:优化方案1:将库存字段number字段设为unsigned,当库存为0时,因为字段不能为负数,将会返回false//库存减少$sql="update ih_store set number=number-{$number} where sku_id=$sku_id and number>0";$store_rs=mysql_query($sql,$conn);if(mysql_affected_rows()){insertLog(库存减少成功);}优化方案2:使用MySQL的事务,锁住操作的行0){//生成订单$order_sn=build_order_no();$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)values($order_sn,$user_id,$goods_id,$sku_id,$price)";$order_rs=mysql_query($sql,$conn);//库存减少$sql="update ih_store set number=number-{$number} where sku_id=$sku_id\";$store_rs=mysql_query($sql,$conn);if(mysql_affected_rows()){insertLog(库存减少成功);mysql_query("COMMIT");//事务提交即解锁}else{insertLog(库存减少失败);}}else{insertLog(库存不够);mysql_query("ROLLBACK");}优化方案3:使用非阻塞的文件排他锁0){//库存是否大于0//模拟下单操作$order_sn=build_order_no();$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)values($order_sn,$user_id,$goods_id,$sku_id,$price)";$order_rs=mysql_query($sql,$conn);//库存减少$sql="update ih_store set number=number-{$number} where sku_id=$sku_id\";$store_rs=mysql_query($sql,$conn);if(mysql_affected_rows()){insertLog(库存减少成功);flock($fp,LOCK_UN);//释放锁}else{insertLog(库存减少失败);}}else{insertLog(库存不够);}fclose($fp);优化方案4:使用redis队列,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,推荐使用(mysql事务在高并发下性能下降很厉害,文件锁的方式也是)先将商品库存如队列connect(127.0.0.1,6379);$res=$redis->llen(goods_store);echo $res;$count=$store-$res;for($i=0;$ilpush(goods_store,1);}echo $redis->llen(goods_store);抢购、描述逻辑connect(127.0.0.1,6379);$count=$redis->lpop(goods_store);if(!$count){insertLog(error:no store redis);return;}//生成订单$order_sn=build_order_no();$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)values($order_sn,$user_id,$goods_id,$sku_id,$price)";$order_rs=mysql_query($sql,$conn);//库存减少$sql="update ih_store set number=number-{$number} where sku_id=$sku_id\";$store_rs=mysql_query($sql,$conn);if(mysql_affected_rows()){insertLog(库存减少成功);}else{insertLog(库存减少失败);}

上述只是简单模拟高并发下的抢购,真实场景要比这复杂很多,很多注意的地方,如抢购页面做成静态的,通过ajax调用接口。

再如上面的会导致一个用户抢多个,思路:

需要一个排队队列和抢购结果队列及库存队列。高并发情况,先将用户进入排队队列,用一个线程循环处理从排队队列取出一个用户,判断用户是否已在抢购结果队列,如果在,则已抢购,否则未抢购,库存减1,写数据库,将用户入结果队列。

我之间做商城项目的时候,在秒杀这一块我直接用的redis,这段时间看了看上面的几种方法,虽然各有不同,但是实现目的都一样的,各位自己选择,开心就好。

php+redis实现抢购功能

php如何处理抢购类功能的高并发请求

PHP通过加锁实现并发抢购功能

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。