架构问题--削峰填谷
削峰填谷
瞬时集中突发性的流量在系统中是很常见的问题,在系统的架构中需要针对相关的业务场景做良好的设计;不仅维护系统的稳定,还能很好的解决业务问题,提高并发性能。削峰填谷是在应对突发性流量的时候最常用的设计思想。
问题分析:体现在应用的处理请求的能力是有限的,但是请求的数量不是均衡的,通常具有瞬时性,时段性;什么意思呢,就是在某个时间端,请求的流量会突增,甚至超过系统所能处理的请求,之后可能又突降,系统空闲资源多;就形成了基于系统负载能力上下的流量高峰低谷。显然这会造成系统的不稳定,甚至系统的雪崩,所以在系统架构设计的时候需要考虑这点。
案例:秒杀业务,上游业务发起下单请求,下游业务执行秒杀业务(库存检查,库存冻结,余额冻结,生成订单等等),下游业务处理的逻辑是相当负载的,并发能力是有限的,如果上游服务不做限流策略,瞬时可能把下游服务压垮,甚至造成雪崩,服务不可用。
策略:通常我们会在网关层做流量的限制,就是通常说的限流;同时会部署更多的下游服务实例,来分担流量压力,就是通常说的负载均衡;但这是不够的,在实际业务场景中我们很可能没有足够的服务器资源,或者说为了某个场景使用大量服务器成本太高,因为多数时候是闲置的(当然我们可以购买流量服务器,在不使用的时候回收,但这不是我们这边讨论的问题,这边更多的是基于,系统架构设计方面来做削峰填谷);所以我们需要在上游服务和下游服务之间设计一种能够缓解突刺流量的方案;让高峰流量填充低谷空闲资源,达到系统的合理利用和稳固。通常我们会使用MQ来做削峰填谷。
使用MQ:合理利用MQ的推(push,服务器主动推送给客户端)和拉(pull,客户端主动拉取) 的模式;在kafka中使用的pull模式;RabbitMq使用的是(push和pull);很清晰,Push模式下,下游服务是无法控制消息的,只能被动的接收,很可能处理不过来,但是又无法控制消息来的速率;所以可以采用主动拉取的模式,根据服务本身的处理能力,做流量控制。
秒杀案例回溯:在秒杀问题中,并发的请求是瞬时的通常时几分钟或者几十秒;但是数据库的写的并发是有限的;如果大量的请求直接穿透数据库,很可能使系统崩溃;这个时候我们可以使用消息中间件(MQ)将请求的流量异步到MQ中,然后下游服务异步去消费消息。这样在下游服务能够根据自身的并发处理能力,控制消费消息的速度,使得数据库的真实写请求控制在能力之内;在使用MQ的过程中推荐使用pull的模式,主动去拉取消消息消费。注意:在这个过程要注意,要时刻监控消息队列的消息堆积,超过一定量的时候,增加消息处理机(就是上面讲到的水平扩容增加服务实例),之所以能够允许消息的短暂堆积,是因为从业务场景上用户对短暂的延时是可以容忍的。进一步分析,可以把下游业务执行秒杀业务(库存检查,库存冻结,余额冻结,生成订单,积分,优化券服务等等)继续通过消息中间解耦,提高核心业务入库的能力,提高并发。
小结
- 在解决高并发下的削峰填谷,首先要做好容量的分析(这个是很复杂的,这边不展开来讲),下面这张图展示了容量分析的方法和过程。
- 使用MQ做异步消息解耦,使用主动拉取的模式来处理,限制流量做到削峰填谷