当前位置: 首页 > 后端技术 > PHP

关于PHP高并发抢购系统设计

时间:2023-03-29 18:16:32 PHP

content并发抢购系统注意事项宽带使用率会瞬间暴涨,需要注意对同一台服务器上其他应用的影响。(项目解耦,独立部署高并发应用)(2)服务器高负载运行,容易出现崩溃。在重启服务器的场景下,需要提前考虑内存(redis)的数据备份和恢复,防止用户抢购数据丢失。(3)高并发应用首先要注意稳定性,其次才是性能优化。(4)一台服务器最多支持多少个并发的nginx服务例如:worker_processes8;worker_rlimit_nofile102400;使用epoll;worker_connections102400;ulimit-ncat/proc/sys/fs/file-max架构设计(1)LVS服务,负载均衡调度,采用RD模式,通过修改数据包的目的MAC地址进行转发。这种方式性能好,适用于高并发应用的大规模部署负载均衡机。;抗负载能力强,工作在网络第4层,只做分发,不产生流量;工作稳定,拥有完善的双机热备方案(2)keepalive(vrrp协议方式)进行心跳检测,支持应用高可用。(3)nginx工作在网络的第7层,因此可以对http应用本身实现分流策略, 可以说是对LVS负载的一种补充。Nginx通过采用异步非阻塞工作模式和epollIO模型,高效处理高并发请求。(4)页面动态数据、用户数据、抢购商品数据存储在Redis中。(5)将用户抢购的记录标识保存在Redis服务器上。在nginx负载均衡端,通过lua脚本过滤用户抓包记录。(6)在realserver端部署nginx和php,realserver可以参与负载端调度。(7)mysql服务器集群采用一主多从部署,master加载数据写入和同步给slave,slave负责数据读取。推荐使用mysql代理组件图集, 实现php端对mysql读写的透明操作。核心代码实现背景假设每个用户只能购买一件商品。预先准备好的数据抢购入redis的总数,比如100000条数据;//申请rediswatch乐观锁$amount=$redis->get('goods_amount');if($amount>0){$userInfo=$reids->get('user_info_crc32(url_token)',array('userId'=>120,'....'));if(empty($userInfo)){$ret=$redis->multi()->decr('goods_amount')->exec();if($ret){$reids->set('user_info_crc32(url_token)',array('userId'=>120,'....'));根据crc32(url_token)的唯一索引,创建用户抢到的商品的标识。(同时可以设置ID的有效期,比如10分钟);write("user_id",{u??ser_id}_success.log);}else{//提示抢购失败}}else{$redis->unwatch('goods_amount');//提示抢购失败}else{//抢购结束,关闭入口}}(1)当下一次抢购请求到来时,在nginx服务器的lua端,查看通过googs_amount抢购的商品数量判断抢购是否结束,再判断user_info_crc32(url_token)是否抢购成功,成功则跳转到订单页面,否则执行抢购流程。(2)将高并发静态资源直接存放在CDN服务器上,减轻服务器访问请求的压力。(1)预热商品数据,提前存入redis,如商品名称、属性等。(2)使用innodb数据库引擎在高并发场景下的读操作有优势。创建合理的表结构,尽可能减少链表查询,合理设计表中的冗余字段。SQL查询可以使用索引。(3)用户浏览商品详情页(需要在redis端做动态数据缓存)(4)用户点击购买跳转到订单详情页(包括用户基本信息,商品信息,支付方式,点消耗等)查询压力大,使用redis缓存策略)(5)提前生成订单数据,user_id留空,同时通过redislpush,将连续的订单id同步到redis分布式集群提前,redis集群支持心跳检测,可以自动进行服务崩溃切换。(6)用户提交订单后,在redis服务lpop中获取一个订单id,根据订单id条件更新用户user_id等信息。开始;更新mt_accountsetuser_id=100whereorder_id=$orderIdanduser_id=0limit1;犯罪;