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

内容
并发抢购系统注意事项
高并发架构设计描述
程序端核心代码实现
订单流程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

架构设计

(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;

时间: 2024-08-06 07:26:37

关于PHP高并发抢购系统设计的相关文章

通过请求队列的方式来缓解高并发抢购(初探)

通过请求队列的方式来缓解高并发抢购(初探) 一.背景 在移动互联网高速发展的时代,各种电商平台的抢购业务变得越来越火爆,抢购业务所带来的高并发问题值得我们去探索,主要涉及的方面包括处理和响应速度.数据的一致性等.抢购开放的一瞬间,可能有成千上万的下订单请求发送到服务器去处理,如果只是简单的请求处理响应方式,不做任何处理,导致的结果很可能是很多客户很长时间得不到响应,根本不知道自己是否下订单成功,或者下订单的数量已经超过了商品的数量,这就导致了超发的问题. 二.设计思路 1.用户在下订单之前当然是

系统架构~高并发日志系统设计

对于一个项目来说,日志是必须的,一般日志的持久化方式有文件和数据库,而在多数情况下,我们都采用文件系统来实现,而对于高并发的情况下,频繁进行I/O操作,对系统的性能肯定是有影响的,这个毋庸置疑!针对这种高并发的场合,我们采用一种缓存队列的方式来处理这个Case是比较明智的,本文主要是向各位展现一下,我所设计的<高并发日志系统设计>,如在功能上有什么需要改进的地方,欢迎各位来回复. 一 项目结构图 二 项目实现代码 /// <summary> /// 工作任务基类 /// </

[日常] 高并发抢购方案的思考

经常在面试中被问到如何设计一个高并发环境下的抢购方案,虽然网上的资料已经很多了,但是都是很简单的说了一些用队列之类的套话,没有更详细的细节考虑.被问的实在是太多了,不得已我也仔细想想这些该怎么设计.抛开运维阶段的多层负载均衡,直接只说PHP的业务层面的逻辑. 整个流程如下:web界面点击抢购==>弹出答题弹窗==>答对判定当前队列长度==>队列未满就进入队列,显示排队中(状态),使用wbsocker实时关注用户状态 ==>答错再答基本就没戏了返回失败 ==>队列满了,返回失败

高并发系统设计与时间和空间的平衡

高可用上文我们已经讲过了,可当前互联网时代,怎么少的了高并发呢?高并发和高可用一样, 已经变成各个系统的标配了,如果你的系统QPS没有个大几千上万,都不好意思跟人打招呼,虽然可能每天的调用量不超过100. 高并发这个词,我个人感觉是从电商领域开始往外流传的,特别是电商领域双11那种藐视全球的流量,再把技术架构出来分享一把,现在搞得全互联网都在说高并发,而且你注意回忆一下所有你看到的高并发系统,往往都逃不开一个核心概念,那就是缓存+哈希,一切都是以这个概念和基础的,仿佛这就是高并发的核心技术了.

php如何应对秒杀抢购高并发思路

我们常用QPS(Query Per Second,每秒处理请求数)来衡量一个web应用的吞吐率,解决每秒数万次的高并发场景,这个指标非常关键. 举个栗子:假设一个业务请求平均为100ms,同时系统内有20台apache web服务器,MaxClients(apache的最大连接数)设置为500,那么理论QPS峰值就是20*500/0.1=100000(理论与实际肯定有差异). 这系统貌似理论上来说很强大1秒钟处理100000个请求,实际当然没有这么理想.在高并发的实际场景下,机器都处于高负载的状

高并发高性能场景(抢购、秒杀、抢票、限时竞答)解决方案

技术指标: PV(Page View, 页面浏览量)在千万级别QPS(Query Per Second, 每秒处理请求数)在百万级别数据量在千亿级别接口响应速度不能超过150毫秒用户提交请求到页面呈现不能超过3秒 架构设计:1. 从LAMP架构转为面向服务架构(服务可以用多种开发语言实现,不受一种开发语言限制)2. 对海量数据做Sharding分片,分库分表3. 从有状态服务改为无状态接口服务(便于分布式部署)4. 精心设计的数据层(存储.压缩.索引)5. 分布式系统最终瓶颈(CPU.内存.存储

PHP解决抢购、抽奖等阻塞式高并发库存防控超量的思路方法

如今在电商行业里,秒杀抢购活动已经是商家常用促销手段.但是库存数量有限,而同时下单人数超过了库存量,就会导致商品超卖甚至库存变负数的问题. 又比如:抢购火车票.论坛抢楼.抽奖乃至爆红微博评论等也会引发阻塞式高并发问题.如果不做任何措施可能在高瞬间造成服务器瘫痪,如何解决这个问题呢? 这里提出个人认为比较可行的几个思路方法: 方案一:使用消息队列来实现 可以基于例如MemcacheQ等这样的消息队列,具体的实现方案这么表述吧 比如有100张票可供用户抢,那么就可以把这100张票放到缓存中,读写时不

PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法

如今在电商行业里,秒杀抢购活动已经是商家常用促销手段.但是库存数量有限,而同时下单人数超过了库存量,就会导致商品超卖甚至库存变负数的问题.又比如:抢购火车票.论坛抢楼.抽奖乃至爆红微博评论等也会引发阻塞式高并发问题.如果不做任何措施可能在高瞬间造成服务器瘫痪,如何解决这个问题呢?这里提出个人认为比较可行的几个思路方法: 方案一:使用消息队列来实现 可以基于例如MemcacheQ等这样的消息队列,具体的实现方案这么表述吧比如有100张票可供用户抢,那么就可以把这100张票放到缓存中,读写时不要加锁

高并发系统设计

高并发系统设计 半同步半异步I/O的设计模式(half sync/half async)