12月28, 2019

秒杀设计

压测工具

  • 安装

    yum -y install httpd-tools

    ab -V 检测安装

  • 使用说明
    • 检测接口最大qps

      ab -n100 -c10 http://xxx(并发数10,访问100次 )

nginx限流

  • 按连接数限速,即并发数(ngx_http_limit_conn_module)
  • 按请求速率限速,按照ip限制单位时间内的请求数(ngx_http_limit_req_module)
  • 创建规则:limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;(以用户的ip地址为key来限制请求速率一个请求每秒,对应的名称叫mylimit)
  • 应用规则:limit_req zone=mylimit burst=1 nodelay;(burst的作用是可以在应对突发流量,不会拒绝,保留一定缓存空间;nodelay如果burst设置的很大,后面的请求不需要排队,可以瞬间处理)。
  • 限流算法:1.令牌桶算法 2.漏桶算法 3.计数器

cdn介绍

  • cdn,内容分发网络
  • 缩短访问路径,减少源站压力,提高内容响应速度
  • 为源站提供安全保护

nginx负载均衡算法

  • round-robin(轮循)
  • weight-round-robin(带权轮循)
  • ip-hash(ip哈希)

消息队列介绍

  • 消息队列实际为链表,头插尾出,高并发下容易发生堵塞,为避免消息丢失,可通过写入实时消息队列进行延时处理
  • 分类:实时队列和延时队列
  • 作用
    • 提高请求响应速度,如:创建订单后的流程,发push,短信等
    • 瞬间高并发下, 可起到削峰,如双十一零点并发创建订单
    • 延时队列,时间维度任务触发,如:发货提醒

秒杀系统特点

  • 抢购人数远多于库存,读写并发巨大
  • 库存少,有效写少
  • 写需要强一致性,商品不能卖超
  • 读强一致性要求不高

    秒杀系统难点

  • 稳定性难
    • 高并发下,某个小依赖可能直接造成雪崩
    • 流量预期难精确,过高也造成雪崩
    • 分布式集群,机器多,出故障的概率高
  • 准确性难
    • 库存、抢购成功数、创建订单数之间的一致性
  • 高性能难
    • 优先成本下做到极致的性能

秒杀系统架构原则

  • 稳定性
    • 减少第三方依赖,同时自身服务器部署也需要做到隔离
    • 压测,降级,限流方案,确保核心服务可用
    • 需要健康度检测机制,整个链路避免单点
  • 高性能
    • 缩短单请求访问路径,减少io
    • 减少接口数、降低吞吐数据量、请求次数减少

扣库存方案

  1. 下单减库存?
    • 并发请求->创建订单(恶意下单&不会超卖)->扣库存->支付
  2. 支付减库存?
    • 并发请求->创建订单(订单超卖)->支付(订单支付不了)->扣库存
    • 并发请求->扣库存->创建订单->支付(不支付库存卖不出)

扣库存方法

  1. 预扣库存实现方案:
    • 先扣除库存,然后创建订单、支付
    • 10分钟内不支付则取消订单,避免不支付库存卖不出问题
  2. 极高并发下怎么做到单服务机智性能
    • 减少上下文切换(有效压榨cpu)
    • 减少阻塞式I/O
      • rpc调用
      • 磁盘读写
  3. 无io怎么做
    • 拆解-扣库存与写订单分开
    • 用内存
    • 用本地内存
  4. 本地减库存,集群机器挂了怎么办?怎么保证不少买
    • 预留buf,统一减库存
  5. 流程
    • 初始化库存到本地库存
    • 本地减库存,成功则进行统一减库存,失败则返回
    • 统一减库存成功则写入MQ,异步创建订单
    • 告知用户抢购成功

      读商品信息页

  6. 与库存服务隔离
  7. 商品库一主多从提高读能力
  8. 页面静态化+缓存+db

排队进度查看

如果创建订单海量,怎么解决高性能查排队进展问题? 思路:

  • 数组A存储排队中,待创建订单的用户;数组b用作索引,存储uid对应在数组A中的索引位置
  • 每次从数组A中依次消费数据,并记录最近消费的索引值X
  • 用户来查排队进展时,从hash表B中取出该uid对应存储的索引值Y
  • 索引值Y-索引值X=排队进度值

    无i/o查库存怎么实现?

  • 读取本地库存,无则拉取一次,有则返回(强一致性要求低)
  • 异步脚本定时同步库存至本地

漏斗型流量

客户端->接入层->server->数据

读库存优化

  • 客户端限制刷新频次
  • 接入层限制同一用户请求次数
  • server分布式集群分摊流量

    扣库存优化

  • 客户端防重入(按钮禁用)
  • 客户端限制刷新频次
  • 验证码防削峰
  • 接入层限制同一用户请求次数
  • server分布式集群分摊流量 alt

php apcu

扩展下载地址:http://pecl.php.net/package/APCu

php.ini需要配置:

extension=php_apcu.dll

[APCu]
apc.enabled=1

apc.shm_size=32M

apc.ttl=7200

apc.enable_cli=1

[xdebug]
zend_extension=php_xdebug.dll

xdebug.remote_enable = On

xdebug.remote_handler = dbgp

xdebug.remote_host= localhost

xdebug.remote_port = 9001

xdebug.idekey = PHPSTORM

具体配置可查看http://php.net/manual/zh/apcu.configuration.php

apcu_add -数据存储中缓存的新变
apcu_cache_info -检索缓存的信息从APCu的数据存储  获取数据存储列表(不会返回value),只有定义值的信息
apcu_cas更新旧值和新值
apcu_clear_cache -清除缓存的
apcu_dec -减少存储的值(必须数值型)
apcu_delete -删除存储变量从缓存
apcu_entry -自动读取或生成一个缓存条目
apcu_exists -检查项目存在
apcu_fetch从缓存取存储变量
apcu_inc增加存储的值(必须数值型)
apcu_sma_info -检索高招共享内存分配信息
apcu_store -数据存储区中的缓存变量

注意:php-cli模式运行不能保存到下次运行

在FastCGI模式下重启后将会清除缓存

本文链接:http://zzl.bzpwhite.cn/post/phpseckill.html

-- EOF --

Comments