Actor模型发展的前提
Actor模型现在得到发展得力于下面三个因素:
- 现在后台应用普遍从单机变成了集群,并且多核处理器得到了进一步的发展
- 内存和磁盘价格的下降
- 网速的提升
如果不是计算机硬件得到发展,Actor模型一时半会还很难线程同步模型相匹敌。
Actor模型的基本概念
Actor的核心在于发送消息和接受消息。每一个Actor系统之间的联络都依靠消息的传递,假设现在有两个Actor系统A和B,A会向B发送了一条消息打招呼,或者是通知B要完成某个任务,注意在这里,Actor模型和线程同步模型不同的是A在发送完消息后,并不会等待B回复消息,而是继续干自己应该做的事。那么这个时候B可能会很快回复消息,表示自己很好,向A打招呼,或者是过了一会儿告诉A任务完成了,抑或是失败了,最糟糕的情况就是B不再理你了。
所以在等待B回复消息的过程中,虽然A不会等待着B回复消息,但是之后的A会面临着如下的选择:
- B立马回复了消息
- B不再回复消息
- A在等待过程中对B是否回复消息失去了兴趣
1这种情况还好,但是对于2和3这两种情况,那么A应该如何处理呢?正常的话会做出下面四种选择:
- 等待一段时间,然后重试
- 换另一种方式发送消息
- 通知C,让C去直接通知B
- A一直挂在那里等待,直到第三方通知
你会选择哪个呢?这个暂且不提,A除了向B打招呼外,A也会发送任务给B,让B去做。最理想的情况是B做完了这个任务,并回复给A,但是B也许并没有完成这项任务,A再也收不到来自B的回复,着意味着A必须也要做好出现这个情况的备份方案。所以一般的情况下,A会发送任务给B完成,也一并设置超时时间,一旦超过这个时间,便执行失败的情况的备份方案(重试,或者是报错),如果B在一定的时间内回复了,那么就会取消超时。超时机制成了A和B联络的核心,使得A不再纠结于B会出现什么情况,只要超时,便会认为B出现了问题,执行备份方案。
Actor Supervisors and Workers
一个actor是可以创造另一个actor,此时的创造者称为Supervisor,被创造的Actor称为Worker,类似于下面:
这是一个经典的主从结构,作为Supervisor,它会监控Worker的一举一动,并对它们的行为负责。Supervisor可以发送消息给Worker让其各自独立工作而不会主动等待它们的回复。这意味着每个Worker可以做不同的事,彼此之间不会相互影响,一旦当Worker完成任务时,只需要通知Supervisor即可,由Supervisor统一再发送给上层的actor或者让Worker进行下一个任务。 作为Actor模型,Supervisor也不会苦苦等待Worker工作,它也会设置一个超时时间,一旦过了这个时间,便会启用备份方案处理超时的情况。
Actor的拓展
Actor的可拓展性来源于Supervisor和Worker的工作模式,并且超时机制也在这里面发挥了重要作用。每一个的Worker都可能出现一个空闲的时间段,一旦出现发生,Worker会发送给Superviso其空闲的消息给Supervisor,Supervisor会再次分配任务给Worker。当新的Worker加入的时候,只要发送给空闲的消息给Supervisor,Supervisor便会发布任务给新加入的Worker。并且Supervisor也可以是另一个Supervisor的Worker,这样形成一种层次的结构,使得Actor不断扩展。
Actor模型的资源分配
Actor模型在Worker都空闲的时候,会尽可能的根据RAM和CPU的处理能力平均的将任务分配给Worker进行工作。与传统的线程同步模型不同的是Actor是通过更高层次的抽象去调控线程,使其可以在面临IO等需要等待的操作会释放线程,让其他的actor工作。注意,这个actor并不会被释放,当IO等操作完成时,就会立马工作。这样的模式意味着actor可以动态分配资源,其面临的限制仅仅只是可使用的线程的个数而已。
Actor模型的错误处理
一旦如果Worker挂了,一般会根据之前的设定有下面的方案处理:
- 忽略错误,重试
- 重启Worker,恢复原来的设置
- 关闭这个Worker
- 反馈这个问题给上一级Supervisor
考虑到Actor是一个层次模型:
Actor系统之间会通过心跳机制互相监控,一旦其中一个actor挂了就会引起其它actor关注,启动错误处理机制。当然这个可能会碰上由于网络阻塞等原因导致的actor挂掉的问题,重试的话,会导致网络阻塞更加严重。actor为了处理这个情况,使用circuit breakers机制,与外部交流的消息都会通过circuit breaker,正常情况下circuit breaker是关闭的,但是与外部的连接中断时,circuit breakers会启用,判断并处理是否是网络等原因造成的问题,并发布消息停止其它actor与外部建立连接,减少网络压力。