互联网秒杀方案为了解决超卖,目前流行两种处理方式:1.队列方式,所有请求放入队列,后台从队列按照FIFO处理2.乐观锁方式。
具体方案如下:
1.队列方式,直接将请求放入队列,采用FIFO(先进先出)方式处理。此方式强行将并发请求一一排序,解决了超卖问题。
缺点1:当高并发场景爆掉队列的话,系统将陷入异常,抢购活动中止。
解决方案:1.加大队列服务器内存
2.事先可设置入队最大个数,当超过次数,直接返回已售罄页面(推荐)
缺点2:用户抢购后,无法直观看到最终抢购结果,需要等到队列执行之后才能知道
解决方案:采用长连接通知用户处理结果
2.乐观锁,乐观锁机制大都采用版本号更新。具体实现是所有请求都有资格进行修改库存,但每次修改前会获得一个该库存数据版本,只有版本符号的请求才会修改成功,否则,修改失败。不过此方式会增大服务器CPU计算开销
缺点:服务器CPU消耗大
解决方案:提前预估抢购规模,准备服务器。随时根据情况增加
总结之后,个人更倾向第二种方案,同时为了完善此方案,增加一下几点:
1.提前预约,只有预约资格用户可参加抢购
2.防止恶意抢购,增加动态验证码
3.抢购页面静态化,使用CDN
4.避免通过下单URL直接下单,使该URL动态化。下单页面URL加入服务器随机数做为参数,只有秒杀开始时候才能得到。
5.抢购通过定时任务自动开始,开始后可生成随机下单参数
6.对时,浏览器可能和服务器时间不一致,js固定时间进行对时,保证时间一致性;web服务器对时,每隔一分钟所有web服务器和对时服务器进行时间同步
nginx方面的一些设置
1.ngx_http_limit_conn_module 限制连接数模块
通常用来限制同一IP地址的可并发连接数
相关文档:
注意:$binary_remote_addr而不是$remote_addr,$remote_addr的长度为7到15个字节,它的会话信息的长度为32或64 bytes,$binary_remote_addr的长度为4字节,会话信息的长度为32字节,这样设置1M的一个zone时,用$binary_remote_addr方式,该zone将会存放32000个会话。
2.ngx_http_limit_req_module 限制请求数模块
通常用来限制同一IP地址单位时间可完成的请求数,限制的方法是采用漏桶算法(Leaky Bucket),每秒处理固定请求数量,推迟过多请求,超过桶的阀值,请求直接终止返回503
相关文档:
3.基于nginx的Tengine分支ngx_http_limit_req_module
nginx类似,不过支持多个变量,并且支持多个limit_req_zone及forbid_action的设置。 相关文档: 4.基于nginx的Senginx分支的ngx_http_limit_req_module
称之为基于条件的限速功能,在Tenginer的limit_req模块基础上,增加condition参数,在条件为真时执行限制动作。 相关文档: 5.基于nginx的Senginx分支的ngx_http_ip_behavior
称之为行为识别模块,访问行为识别模块的作用是对用户访问网站的行为进行监控
相关文档: 6.基于nginx的Senginx分支的ngx_http_robot_mitigation
称之为HTTP机器人缓解,Robot Mitigation模块采用了一种基于“挑战”的验证方法,即向客户端发送特定的、浏览器能解析的应答,如果客户端是真实的浏览器,则会重新触发请求, 并带有一个特定的Cookie值,Robot Mitigation模块会依据此Cookie的信息来决定是否放行此请求。
相关文档: