理解 skynet 架构

对于 skynet 架构的理解

Intro

最近迷上了云风的 skynet 框架,但苦于 skynet 上手难度确实比较高,于是就萌生了搞清楚 skynet 的设计,然后自己拿 python 抄一个架构类似的游戏服务器的想法。

于是,就此机会,我从个人使用体验、文档、被到处转载的 blog 的基础上,稍微做了一些思考。

skynet 的消息机制

首先要提起的是 skynet 中服务的概念。

skynet 的服务是一个个 lua 文件,当然根据 wiki 的说法,也可以是其他任意一种随你喜欢的语言编写。

引用自wiki - GettingStarted

最后是服务工作阶段,当你在初始化阶段注册了消息处理函数的话,只要有消息输入,就会触发注册的消息处理函数。这些消息都是 skynet 内部消息,外部的网络数据,定时器也会通过内部消息的形式表达出来。

从 skynet 底层框架来看,每个服务就是一个消息处理器。

从这里可以看到,服务的主要用法是消息回调。skynet 框架分发消息给服务,服务是 consumer,但同时服务也可以发出消息,因此服务也是 producer。

skynet 的服务处理消息回调的方式是启动一个 co-routine,每个消息都分别启动一个 co-routine,然后在 co-routine 里调用使用skynet.dispatch绑定的消息处理方法。

显然,用 co-routine 的处理方式是不够高效的,因为 co-routine 的计算并不是真正并行,所以在服务之上,还有多线程的调度器,允许多个Lua虚拟机里的 co-routine 同时运行。

注意是多个Lua虚拟机——所以虚拟机内的co-routine并不会出现数据竞争,service 之间以 actor 模式通信,线程间高效地传递数据,也就是服务间的消息机制。因此 skynet 的 wiki 文档才会说,单个进程内的 skynet 有最高效的并行性能。

扫描二维码关注公众号,回复: 4223004 查看本文章

大体来说,skynet的架构是这样子的。

层级 名称 责任
调度层 skynet进程 调度线程轮流执行lua虚拟机。
消息层 消息队列 分发消息给服务
服务层 服务 发布消息,设置消息处理回调
回调层 消息回调 每个消息回调都会启动一个新的 co-routine 执行回调函数

和云风演讲中提到的 skynet 就是个小的操作系统不谋而合。线程就是CPU,Lua虚拟机就是skynet这个“操作系统”下被调度的进程,轮流占用CPU。

猜你喜欢

转载自my.oschina.net/u/3888259/blog/1841056