探索skynet(五):随笔


最近准备在组内做一个有关skynet的分享,所以对skynet产生了一些“形而上”的思考。这篇文章将不涉及具体的代码细节,就是就着skynet这个框架“扯扯淡”,随便写写。

skynet的核心是什么

skynet从Erlang借鉴而来,主要借鉴它的Actor模型,用以充分利用多核实现并行计算。所以skynet可以说是一个C语言+lua语言实现的Actor模型框架。

skynet中的每一个Actor,原则上,都是一个so库。每个Actor,对应于一个自己的消息队列。所有消息队列又串成了一个消息队列的大队列。多个工作线程,不断的从大队列中拿出消息队列,取出消息,找到对应的Actor(也就是so库),将消息扔给so库去处理。从这个角度来说,Actor(so库),不过是一个消息处理器

当然,所有的Actor都可以用C语言来写,做成so库的形式。但是这样开发效率偏低,所以skynet提供了一个特殊的so库,即snlua.so库。它封装了一个lua虚拟机,当框架把消息扔给snlua.so处理的时候,snlua.so一甩手,就扔给了对应的lua代码。于是,我们可以用lua代码来编写Actor,然后用snlua.so把这段lua代码加载起来就可以了。

所以,skynet的核心,一个是基于消息队列的任务调度;另一个是snlua.so所提供的可以用lua编写Actor的能力。

对比Erlang

绕了这么一圈,几千行C代码,skynet对比Erlang优势在哪里?

我觉得,第一个优势就是lua和C的数据抽象能力,比Erlang要强很多。这对于编写业务逻辑复杂多变的游戏服务端程序,是大有裨益的;而Erlang,可能更适合与编写业务逻辑单一,但是并发性能要求很高的基础组件。

第二个(对云风来说的)优势在于,云风对于C和lua太熟悉了,完成这样一套类似Erlang,又实际使用lua+C的框架之后,他之后招人、培训都会方便很多……对于创业公司来说,技术选型上肯定还是倾向于公司内的大牛所熟悉的技术。

对比BigWorld

BigWorld是我们项目目前使用的游戏引擎,skynet与之相比,最大的一点不同就是,skynet只相当于BiogWorld的一个子系统。对于场景管理、与客户端的网络通信协议、数据库ORM模块等等,统统没有支持。所以说,skynet是很“轻量”的,或者说,skynet的核心是很小的。这在另一方面,也带来了更高的自由度。

当然,skynet相比于BigWorld也有一个很大的优点,就是计算任务之间的隔离性。设想,如果出现某一个计算过程非常耗时,对于skynet这种架构来说,它最多占满一个核心,而其他任务则可以调度到其他核心进行计算,影响不会扩散;但是对于BigWorld这种多进程、每个进程单线程的架构来说,如果一个进程内出现了耗时的计算任务,那么同一个进程内的其他计算逻辑都会受到影响。究其根本在于,skynet对于计算任务的调度是实时均衡的,而BigWorld则会根据当前服务器上玩家的分布,做一个预先的分配。这也将导致这样一种奇特的效果:如果由于人数过多导致的负载过高,隔离性较好的skynet会出现所有玩家要卡一起均匀的变卡的状况;而隔离性不好的BigWorld,则是人员密集的地方卡的比较严重,而人员较少的地方则比较流畅。感觉隔离性特性和其导致的结果正好反过来了。


“形而上”的东西大概就说这么多吧,等组内的分享结束之后,我会把PPT也放上来,里面会有一些图示,可能更加有助于对skynet整个框架的理解。

推荐阅读:
探索skynet(二):skynet如何启动一个服务
探索skynet(三):消息队列

转载请注明出处: http://blog.guoyb.com/2017/10/12/skynet-5/

欢迎使用微信扫描下方二维码,关注我的微信公众号TechTalking,技术·生活·思考:
后端技术小黑屋

Comments