• 关于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;
     
  • 相关阅读:
    Spring Cloud Hystrix Dashboard的使用 5.1.3
    Spring Cloud Hystrix 服务容错保护 5.1
    Spring Cloud Ribbon 客户端负载均衡 4.3
    Spring Cloud 如何实现服务间的调用 4.2.3
    hadoop3.1集成yarn ha
    hadoop3.1 hdfs的api使用
    hadoop3.1 ha高可用部署
    hadoop3.1 分布式集群部署
    hadoop3.1伪分布式部署
    KVM(八)使用 libvirt 迁移 QEMU/KVM 虚机和 Nova 虚机
  • 原文地址:https://www.cnblogs.com/lazb/p/6961615.html
Copyright © 2020-2023  润新知