秒杀其实关注的是两个点:
一、高并发系统稳定性
1、限流
令牌桶:令牌桶算法是程序以r(r=时间周期/限流值)的速度向令牌桶中增加令牌,直到令牌桶满,请求到达时向令牌桶请求令牌,如获取到令牌则通过请求,否则触发限流策略
漏桶:漏桶算法是访问请求到达时直接放入漏桶,如当前容量已达到上限(限流值),则进行丢弃(触发限流策略)。漏桶以固定的速率进行释放访问请求(即请求通过),直到漏桶为空。
计数器算法:如使用redis的加1方法,结束的时候就减1,达到阈值就限流;
2、削峰
利用消息中间件异步;
利用图片验证码、计算等减少蜂拥;
3、缓存
4、页面静态化
5、服务独立
二、超卖问题
核心思想就是保证库存递减是原子性操作
1、redis递减 通过 redis->incrby(‘product’, -1) 得到递减之后的库存数;
2、数据库 update product set num=num-1 where num>0; 但是数据库使用乐观锁的性能相对较差,不建议使用;
3、分布式锁 用redis来做一个分布式锁,reids->setnx(‘lock’, 1) 设置一个锁,程序执行完成再del这个锁。
锁定的过程,不利于并发执行,大家都在等待锁解开,不建议使用。
4、消息队列将订单请求全部放入消息队列,然后另外一个后台程序一个个处理队列中的订单请求。
并发不受影响,但是用户等待的时间较长,进入队列的订单也会很多,体验上并不好,也不建议使用。而且如果队列涌入消息的速度远远大于消息处理的速度的话,消息都在队列中堆积,整个系统的性能也很低。