一、简介
在调用方与被调方之间设计一个队列,有助于缓冲请求量,平滑处理请求,达到消峰的目的,降低峰值请求对服务性能、可用性的影响和服务失败等问题。有效防止被调方因高负载而产生间歇性的不可用。
二、队列设计
2.1、场景描述
很对设计中都会涉及到调用远端云服务,尤其是微服务化的架构,这种调用就更加频繁了。如果被调方出现间歇性的高负载,该服务的性能就会受到影响,为了不造成雪,崩服务如果有弹性设计,可能会选择执行限流或者降级,甚至直接熔断,这肯定是我们最不希望看到的现象。
这种间隙性负载可能出现在什么情况下?
- 多个任务节点同时访问一个服务处理相同业务。
- 突发的流量峰值。服务无法处理高并发的流量,部分请求会直接拒绝掉。如果服务自身没有很好的处理这些流量的请求,很可能直接造成服务自身的不可用。
如下图:
2.1 添加队列
在A、B、C三个实例与Worker服务之间添加一个Message Queue,会有什么效果呢?
- instance与worker之间解耦,实现异步。
- instance可以按照自己的速率发送message到queue。
- worker可以按照自己的处理能力去queue取数据处理。
如下图:
instance与worker可以按照自己的速率去发送与处理数据。即使worker出现不可用,也不会影响instance,只要queue保存message知道worker去消费处理就可以。
2.3 优势
- 该模式能够最大化提升系统的可用性,即使worker出现不可用,instance也可以继续想message发送消息。
- 有效提升系统的伸缩性,因为instance与worker实现解耦,可以随意增加或删除节点。
- 实现成本控制,queue起到了消峰的作用,使worker可以平滑处理message,并不需要为了满足峰值去部署更多的资源,只需要满足平均负载就可以。
2.4 缺陷
- 必须实现worker对于处理速率的控制,加入队列的目的就是为了平滑处理请求,避免高负载,但是worker的负载虽然控制了,这种压力可能透传到DB。需要在测试期间找到worker最佳的处理速率。
- queue是单通道的,如果想要实现实现worker对instance的回包。需要借助双通道策略,一发一收(这里不做总结)。
三、总结
基于队列的负载均衡对应经常出现负载的服务是很有效的优化手段、该模式是异步处理的,如果想要得到快速的处理响应,并不推荐使用该设计。