设为首页 收藏本站
查看: 986|回复: 0

[经验分享] 关于PHP高并发抢购系统设计

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-12-30 17:46:06 | 显示全部楼层 |阅读模式
内容  并发抢购系统注意事项
  高并发架构设计描述
  程序端核心代码实现
  订单流程mysql 端并发解决方案
  注意事项
  (1)高并发环境下,对于服务器cup、内存、网络宽带使用率会瞬间暴涨,需要注意对同服务器上其他应用的影响。(项目解耦,高并发应用独立部署)
  (2)服务器高负载运行,容易出现死机,重启服务器场景,要提前考虑内存(redis)数据备份与恢复,防止用户抢购数据丢失.
  (3)高并发应用首先要注重稳定性,其次是性能上优化.
  (4) 一台服务器能够支持多少并发量
  nginx服务为例:
  worker_processes 8;
  worker_rlimit_nofile 102400;
  use epoll;
  worker_connections 102400;
  ulimit -n
  cat /proc/sys/fs/file-max
  架构设计
DSC0000.png

(1)LVS服务, 做负载均衡调度, 采用RD模式, 通过股修改数据包的目的MAC地址实现转发,该方式性能好, 对并发高应用,适合大规模部署负载均衡机器;抗负载能力强、是工作在网络4层仅作分发之用,没有流量的产生;工作稳定,自身有完整的双机热备方案  (2)keepalive(vrrp协议方式) 做心跳检测,支持应用具有高可用性。
  (3)nginx工作在网络的7层,所以它可以针对http应用本身来做分流策略, 可用说对LVS负载的补充。nginx高效处理高并发请求在于采用异步非阻塞工作方式和epoll IO 模型。
  (4)页面动态数据,用户数据,抢购商品数据采用Redis存储。
  (5)用户抢购记录标识存储在Redis服务器端。在nginx负载均衡端,应用lua脚本做用户抢购记录过滤。
  (6)real server端部署 nginx与php, 同时 real server 可以参与负载端调度。
  (7)mysql server cluster 端采用一主多从部署,master负载数据写及同步到slave, slave负责数据读取。推荐应用mysql代理组件atlas, 实现对php端对mysql读写透明操作。
  核心代码实现
  背景
  假设每个用户只允许抢购一件商品。
  预备数据
  抢购商品总数存入redis中, 比如十万个数据
  $redisObj = new redis();
  $redisObj->set('goods_amount', 1000000);
  $redis->watch('goods_amount'); //应用redis watch 乐观锁
  $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)唯一索引创建改用户已抢过商品的标识。(同时标识可以设置一段时间有效期,例如10分钟);
  write("user_id", {user_id}_success.log);
  }else {
  //提示抢购失败
  }
  } else {
  $redis->unwatch(‘goods_amount');
  //提示抢购失败
  } else {
  //抢购结束, 封闭入口
  }
  }
  (1)下一个抢购请求到来时,在nginx服务器lua端,检查googs_amount抢购商品数量,判断抢购有没有结束,在判断user_info_crc32(url_token)有没有抢过成功,如果成功跳转到下单页面,否则执行抢过流程。
  (2)抢购首页直接高并发静态资源存储在cdn 服务端, 来减轻服务端访问请求的压力
  mysql端并发解决
  (1)抢购商品数据预热,提前存储在redis中,比如商品名称,属性等等。
  (2)采用innodb 数据库引擎,在高并发场景读操作有优势,合理创建表结构,尽可能的减少链表查,可以适当设计表中冗余字段,sql查询能够必须走索引。
  (3)用户浏览商品详情页(需要在redis端做动态数据缓存)
  (4)用户点击购买跳转到订单详情页(包括用户基本信息,商品信息,支付方式,积分消费等数据考虑对数据库并发查询压力,要采用redis缓存策略)
  (5)订单数据提前生成,user_id留空,同时通过redis lpush,把连续订单id,提前同步到redis分布式集群,redis集群支持心调检测,能够自动做服务奔溃切换。
  (6)用户提交订单后,  在redis服务lpop拿到一个订单id, 根据订单id条件更新用户user_id等信息。
  begin;
  update mt_account set user_id=100 where order_id=$orderId and user_id=0 li mit 1;
  commit;

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-429748-1-1.html 上篇帖子: CentOS 通过yum来升级php到php5.6 下篇帖子: php抓取一个页面的图片
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表