前言:传统同步阻塞编程模型中,我们最关注的问题是线程不够用,即没有充分利用计算资源,到了异步编程模型中,我们的线程资得到了充分的利用,但是我们要开始关心内存资源问题了,所以我们要在设计系统的时候做好拥塞控制,避免内存OOM的发生。
这里额外的说一下:一说到同步异步编程,我们很容易的和IO尤其是socket的阻塞非阻塞联系起来,原因是明显的:传统的同步编程模型,阻塞线程的部分基本都是做IO的时候导致的,现在的异步编程,主要解决的非阻塞的地方也是实现了IO的非阻塞,所以,我们可以近似的理解异步编程模型就是IO非阻塞模型!
高吞吐的非阻塞异步编程模型中,通常会涉及到多个非阻塞业务线程、IO事件线程、业务事件线程等,这些线程相互配合完成一个个的业务任务,通常交互的方式就是通过线程池的消息队列传递消息或者事件的形式。虽然核心业务线程是设计为执行非阻塞业务的,但是我们要明确一点:任何系统的吞吐量都是有上限的!例如,我们做IO请求的时候,虽然读写底层socket都是非阻塞的,但是IO发送和接收的速率是不能改变的,网络带宽是不能改变的!我们所追求的非阻塞都是指的不阻塞线程,即不阻塞CPU,不阻塞计算资源,但是我们的业务数据可能要"阻塞"了,即我们的业务数据要在内存中排队了,任何一个系统可用的内存都是有限的,如果我们系统中不做拥塞控制,我们的内存可能要被挤爆了--OOM!
在异步非阻塞编程模型中,我认为的拥塞控制思路是:分清要做拥塞控制的对象,对可能拥塞的对象做控制!
一般的思想是,系统入口层要能提供速率控制,入口的下级层要能提供拥塞反馈给系统入口,一旦拥塞就减少系统入口接收业务请求的速率!
1 非阻塞业务线程池的业务队列是一个考虑点,业务队列不能无限接收业务任务,因为一个任务通常会绑定一块关联的内存数据,排队任务多了会OOM。
2 系统入口处的速率要控制,一般的服务系统的入口都是socket接收器那块,当1中核心业务线程池的处理队列达到上限的时候,我们的接收器要能够暂时停止接收客户端连接来减少业务请求的数量
3 系统出口处拥塞要能反馈给上级,通常的上级指的是业务线程池或系统入口接收器,系统出口通常是向其他系统发送数据的sokcet连接器,当出口发送速率下降的时候,要反馈给上级减少接收业务的速率,当出口发送速率恢复的时候也要反馈给上级恢复业务接收速率。
总结:拥塞控制的本质思想还是流控制,即管道流
(完,这篇文章写的比较粗糙)