理解 skynet 架构

对于 skynet 架构的理解

Intro

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

因而,就此机会,我从我的使用体验、文档、被处处转载的 blog 的基础上,稍微作了一些思考。服务器

skynet 的消息机制

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

skynet 的服务是一个个 lua 文件,固然根据 wiki 的说法,也能够是其余任意一种随你喜欢的语言编写。多线程

引用自wiki - GettingStarted架构

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

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

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

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

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

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

大致来讲,skynet的架构是这样子的。

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

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