最近想给新来的几个实习生和新员工培训一下 skynet 底层实现,于是有了写这篇文章的想法,关于 skynet 底层的文章有很多,但是都有一个问题,就是知识点过于细和分散,而且配图不堪入目,在我看来就是对 skynet 这么好的作品极大的不尊重。而我也不想再重复网络上可以找到的同款文章单调乏味的套路。这篇文章主要就是通过2张图,站在一个更高的高度来俯视 skynet ,快速吸收底层的设计精髓。
并且我也不打算把代码贴上来,然后在上面写满注释,因为 云风 写的代码非常简洁易懂。基本上看一遍就可以理解了。我要做的是对这些代码最终想得到什么效果,为什么这样设计,核心的东西是什么?通过面画把它们串起来,让读者对其中的关键点和相互之间的关系一目了然,并且不容易忘记。
因为其中的知识获取过程就是将每一行代码,在脑海里组织起来最终形成具象的东西。这需要花的时间代价和把它记牢的代价还是挺高的,因为我几年前就看了源码,并且也算理解了里面的知识。但是最近还是不得不重新看一遍才能回忆起来。所以我觉得把它画一遍很有意义,经典的东西就值得花心思为它做点什么。
skynet 的核心就是可以在一个进程内创建很多模块,和一堆模块生产出来的实例,实例之间的资源都是相互隔离的,可以通过收发消息进行交互,这种并发模型被称之为 Actor 模型。
并且通过工作线程的数量和权重信息来确保每个模块很大程度上可以获得合理的线程调度机会。
而这正是 云风 说的 “Skynet 核心不解决什么问题”,那么现在我们就明白了最终想要的效果无非就是:
1)各个模块相互隔离带来的解耦,这个效果有很多好处,如 模块方便移植;
2)因为模块的粒度较小从而更加方便进行灵活的调整。 服务器架构部署可以弹性部署。(可以看看我写的另一篇文章https://www.jianshu.com/p/391881567d57);
3)给多线程并发提供更好条件,更能充分榨干机器性能(相对于内存共享型的多线程并发)这点是精髓;
启动就是解析配置、创建线程、启动 bootstrap 模块,我们也可以自己编写引导模块,或者就不用lua来写代码,全程c/c++ 或者是 go,但是要对消息进行序列化和反序列化。我觉得用 sproto来做 rpc 还是挺不错的。下一篇将以同样手法来详解 sproto