队列削峰
用额外的单进程处理一个队列,下单请求放到队列里,一个个处理,就不会有qps的高并发问题了。场景中抽奖用户会在到点的时间涌入,DB瞬间就接受暴击压力,hold不住就会宕机,然后影响整个业务。队列的长度保持固定,对于如果请求排队在队伍中靠后,比如奖品100个的情况下,中奖率10%,队列里请求任务超过1000时,就直接将后续的抽奖请求返回不中奖。用tair记录排队数,如果奖品没发完,再请空tair,允许请求继续入队列。这样队列起到了降级和削峰的作用。
对于与抽奖无直接关系的流程采用异步
比如抽奖成功之后的发短信功能另起一个线程池专门处理。这样可以提高请求的处理速率,提高qps上升后的乘载能力。
同一时间片内,采用信号量机制
确保进来的人数不会过多导致系统响应超时: 信号量的采用,能够使得抽奖高峰期内,同一时间片内不会进入过多的用户,从底层实现上规避了系统处理大数据量的风险。这个可以配合队列进行限流处理。
消息存储机制
将数据请求先添加到信息队列中(比如Tair存储的数据结构中),然后再写工具启动定时任务从Tair中取出数据去入库,这样对于db的并发度大大降低到了定时任务的频率。但是问题可能会出在保持数据的一致性和完整性上。
必要时候采用限流降级的测流
当并发过多时为了保证系统整体可用性,抛弃一些请求。对于被限流的请求视为抽不到奖。
***************************************************************************************************************************************************************
如果活动中奖品价值都较高,此种情况下,通常奖品数量有限,中奖概率不高,所以即便是抽奖的并发量较大,实际写DB的压力也并不大,即在扣减奖品库存、向DB中插入中奖记录等环节的写压力并不会大。
如果活动发放类似于优惠券的虚拟奖品,数量可能很大,中奖概率非常高,那么当抽奖并发量大时,写DB的压力会很大。
从图中可以看到,经过前面的逐层分流,最终只有少部分请求会进行DB操作。当绝大部分的流量都被通过种种手段分担,系统自然就可以轻松处理剩余的少量流量,这也就意味着系统可以具有非常高的性能。