实现一个ECS+Actor游戏服务器框架(2)

最近在折腾分布式Actor服务器框架。

分布式ActorId

单个集群中的Actor数量用long类型64位足够。

id可分为面相业务与临时id。面相业务可使用服务器编号+人数生成唯一id。可使用服务器标识,进程号等再搭配上时间戳生成临时id。

如何调度Actor?

Actor模型需要保证顺序处理邮箱中的消息,调度的粒度不应该是消息,而是一整个Actor。

假如一个Actor的消息堆积过多,还会造成其他Actor的消息不能及时处理,造成Actor饥饿。

常见调度器设计,将Actor绑定到线程。Actor的执行任务使用双端队列来存储,工作线程从头获取Actor,窃取线程从尾部获取Actor。

这个方法还需要处理竞争问题,当窃取线程越多,队列尾部竞争越大,反而会对CPU造成资源浪费。常见解决方法当没有窃取到任务,则等待更长的时间。

按我的理解,窃取线程也是工作线程转变的,工作线程处理完绑定自身的Actor的任务,去窃取其他工作线程的任务。如果在等待过程中,自身的Actor有消息需要处理,需要立刻打断这个等待。

线程亲和性?

用SynchronizationContext将异步回调抛到原始上下文可避免线程上下文切换的开销,但是如果代码中使用Task.Result等同步阻塞方法,将会死锁。

自定义awaitable是否有必要?

虚拟Actor

Orleans提出了虚拟Actor。 我认为虚拟Actor是Actor模型的下一个必经阶段。首先定义粗粒度的行为接口,之后便可以以本地调用的方式调取远程Actor的方法,非常方便。

返回顶部