文档介绍
文档目的
本文旨在捋清Skynet框架结构及分析源码的具体实现。
使用Skynet已经有几年,期间学习过不少Skynet的资料,但都是零零碎碎的知识,没有形成完善的知识体系,并没有系统地掌握Skynet。因此还是经常会有一些疑问困扰着自己,导致在使用Skynet框架的时候,对自己的服务器架构没有十足的信心。遇到Bug时也不能看透本质,找不到问题的关键,不能做出最适合业务的设计,没有办法以最稳最快最正确的方式解决问题,同样也没办法做进一步的优化。因此我想结合Skynet框架结构来阅读源码,详细了解源码如何实现Skynet框架结构的功能。在了解整体架构的前提下,继续去阅读源码,相信能加深对Skynet的认知,希望大家能喜欢。
通过这几年对Skynet的学习和使用,对Skynet的框架结构已经有了较熟悉的认知,这里主要感谢云风BLOG的记录以及GitHub仓库中WIKI的介绍,这对于新手学习Skynet框架非常有帮助。网上也还有还多分析Skynet的文章和资料,大家可以找到对比着看。
我还设立了Skynet专题包括:信号、线程、网络、锁,原子操作、算法专题等。这些专题是从Skynet项目中提取出来的,是属于计算机编程的重要知识和技能点。特点是:知识通用且重要。这些专题涉及的知识点不止是在Skynet框架或者游戏行业中会用到,在编程中几乎都会涉及,因为这些本来就是计算机编程中基础且重要的部分,程序员都避开不了的,在很多地方都会用到的。
内容目录
【Skynet框架分解】
目的是完全了解并掌握Skynet框架,知道它的优缺点、清楚它能做什么、明白它擅长什么、了解它的特性、最后根据这些知识,继续阅读Skynet源码,探究代码是如何实现Skynet的功能和特性的。
【Skynet源码准备】
在开始阅读Skynet源码之前,需要准备一些必要的Linux环境和工具。当然,最重要的是了解Skynet的目录、编译、运行,因为在阅读源码的过程需要运行Skynet查看效果或者修改一些代码来验证自己的想法。
【Skynet源码赏析】
根据Skynet的项目源码,我会分模块、逐个分析其代码实现,这是最重要也是最复杂的部分。在整个学习生涯中,有种很大的感触是:有图的教程往往能更容易理解和掌握知识。这可以说是符合人类的记忆,学习特点的。在阅读Skynet代码的过程中我也有强烈的意愿:想用图形的方式来表达展示Skynet结构,能更容易理解框架结构和脉络。在这里我使用开源的draw.io来画图,并给出相应的图片。
【Skynet最佳实践】
想必刚接触Skynet的新手,都是知道云风的BLOG网站的,云风大佬在里面分享了自己很多Skynet相关的想法和思路,包括Skynet的设计思路、优化方案、代码设计等。这些文章不仅可以让你了解Skynet的来源,也能让你思考如何设计自己的框架,如何写出更加高效的代码。作为新手刚开始看文章或许不明白不理解,只有在工作有了经验后,反过头来看文章,才会明白为什么云风这么设计,代码为什么这样写,有什么好处。同时阅读Skynet Github中有质量的Issue,吸收同行实践的经验,做到最佳实践,避免踩坑。最后,因为Skynet也是在不断更新进步中,这中间也会参考最新的特性,最新优化的点进行分析。
【Skynet资料分享】
在学习Skynet的过程中,我查阅了很多资料,浏览过很多相关的网站。我认为网上的很多资料对我们学习和掌握Skynet都是非常有帮助的,里面有很多同行和前辈的经验分享,踩坑经历,项目实战等,对于我们学习Skynet和设计自己的架构都非常有帮助。一句话就是人多力量大,经过大家验证的东西一般比较可靠。这部分是分享一些高质量的网站、资料、视频等来帮助大家多方面,全方位,各角度地学习Skynet,让你更容易理解和掌握。
【Skynet专题学习】
目的是跳出Skynet框架,提取出通用的、重要的计算机编程知识,因为这些才是最重要的计算机知识点。在计算机编程的世界中,这些知识点和技能是普遍的,即使换个开源项目,换个服务器框架,脱离游戏行业,这些专题的知识和技能, 设计的思路和优秀的代码风格,都是很有帮助的,面试过程中也是经常考核这些知识点。
【Skynet涉及的Lua语言知识】
学习Skynet必然要用到Lua,语言本身并不难,简单的学习语法之后就能上手使用。但是一些基础且重要的知识,深入的用法还是需要学习的,最好有一些实际的例子,做到最佳实践。在阅读源码的过程中遇到了我都会提及,另外也会推荐一些优秀受欢迎的Lua书籍给大家阅读。
【Skynet涉及的C语言知识】
我在阅读Skynet源码的时候,会遇到一些C语言的知识,毕竟大学毕业也好几年了,实际工作中使用C语言的机会很少,导致有些生疏。因此特意加了相关C语言知识这一部分。目的是为了熟悉C语言,找回对C代码的感觉,使阅读Skynet源码没那么吃力,新手也没那么畏惧。需要注意的是,相关C语言的知识不会很深入,都是了解相关用法,一般我们不需要探究实现方法。假如遇到需要更改底层代码的时候,在深入了解后进行更改。
前期准备
知识准备
在正式开始之前,希望读者有以下的知识准备
1,基础的计算机知识
2,简单的C语言知识
3,了解Lua语言
对于第一点,相信很多人都能做到,这部分不要求你有很深的掌握或者应用,只需要了解知道,能理解即可。无论你是计算机科班出身,还是已经有编程经验,应该都具备最基础的计算机知识,否则你也不会看这篇教程。
对于第二点,Skynet框架底层是通过C语言实现的,会简单的C语言是必要的条件,否则无法对源码进行阅读。但同样的,也不要求你对C语言有多熟悉,因为在对源码进行阅读时,我会同时进行C语言相关语法的解释。
对于第三点,如果已经使用或者了解过Skynet的人来说,完全不是问题。对于没有接触过Lua语言的人来说,也不用担心,Lua语言是个很轻量的脚本语言,可以花几天时间学习一下也够用,后面可以遇到问题再查阅。
参考资料
云风的BLOG:云风的 BLOG (codingnow.com)
这个是Skynet作者云风的网站,里面有很多编程知识的分享,有关Skynet和Lua部分可以优先看看。
Skynet的GitHub地址: Skynet官方项目 (GitHub.com)
Skynet的官方项目地址,里面有WIKI,教程以及各类Issue,对使用Skynet有很大的帮助。
我的知乎主页:不是罗罗 - 知乎 (zhihu.com)
我本人会在知乎分享一些编程文章,肯定是有Skynet相关的,需要的话可以关注一下。
网上任何可以帮助自己资料,都可以借鉴参考。
一些问答
此篇教程面对的人群是什么?
教程面对的主要人群:第一类是刚接触Skynet项目的新人,例如很多是刚毕业,加入游戏行业的学生。如果你的公司使用了Skynet框架,那么此教程对你上手学习Skynet肯定有非常大的帮助。第二类是有一定Skynet使用经验的人,但没有深入了解过Skynet,也没有自己的总结和沉淀,想进一步提高对Skynet的掌握并期望在职场中更进一步或者在寻找新工作机会的人。
需要对 Skynet项目有了解吗?
不需要。虽然这篇教程的方法是先了解Skynet整体的架构,再去阅读源码。但我依然会在开始阶段,先根据自己的知识以及收集的资料,简单清晰地描述Skynet的框架结构,然后再根据这个框架结构带着疑问去阅读源码,从而达到更好的效果。
学习完 Skynet框架和源码后能做什么?
正如云风说的,Skynet并不是一个开箱即用的框架,只有你知道自己想要什么,它才能更好地帮助你。学习完Skynet框架之后,并不代表着你拥有了一套可以实际跑商业项目的代码,但你可以利用它设计出你想要的上层服务器业务架构。而这篇教程是帮助你,更好地掌握和认识Skynet框架,从而使你对自己使用的底层框架有最大把握,有十足的底气去支撑上层业务架构。
学完本教程以后的路怎么走?
我认为学习任何一个框架或者某方面的知识,它最终并不会只局限在某个领域。学习Skynet框架也是如此,只要你用心学习完,最终的收获肯定不只是Skynet框架这么简单。例如:简单地对C语言,Lua语言的使用会熟悉,一般的如何代码设计,项目如何管理和如何优化性能,复杂地对多线程,锁,网络通信,序列化等有认识。其实Skynet是个很优秀很简洁的C语言项目,从别处借鉴了很多优秀的代码设计,有很多可取可学习之处。例如:Skynet代码中对于timer定时器线程的设计,就是借鉴了Linux内核动态定时器的机制,设计非常优秀。通过学习Skynet网络线程,你同样能知道网络编程的很多知识。即使你不使用Skynet,从中学到的知识和思维,在别的领域同样是适用的。所以,希望大家都能坚持下去,不要只学表面,更要学习精髓的东西。
Skynet框架分解
Skynet框架分解(1)
目录为:
基础知识
核心
进程
线程(内核级线程)
协程(用户级线程)
线程和协程的区别
Skynet相关
总结
Skynet特点
Skynet线程
Actor模型
Skynet举例
Skynet服务
服务流程
存在问题
内容为:
Skynet源码准备
Skynet源码准备(2)
目录为:
参考资料
工具准备
VirtualBox
CentOS
Terminal
Samba
Sublime
下载
目录
基于源码的情况下
基于编译的情况下
编译
运行
内容为
Skynet源码赏析
下面开始正式分析Skynet源码,因为代码比较多,所以我打算分模块进行分析
每个模块都分出了一个文件来记录,可以点击文章链接,进入具体章节
Skynet源码之:环境准备(3)
已完成《Skynet源码之:环境准备》
Skynet源码之:环境准备(3) | 不是罗罗 (luozhiwen.com)
Skynet源码之:守护进程(4)
已完成《Skynet源码之:守护进程》
Skynet源码之:守护进程(4) | 不是罗罗 (luozhiwen.com)
Skynet源码之:节点建立(5)
已完成《Skynet源码之:节点建立》
Skynet源码之:节点建立(5) | 不是罗罗 (luozhiwen.com)
Skynet源码之:服务管理(6)
已完成《Skynet源码之:服务管理》
Skynet源码之:服务管理(6) | 不是罗罗 (luozhiwen.com)
Skynet源码之:消息队列(7)
已完成《Skynet源码之:消息队列》
Skynet源码之:消息对列(7) | 不是罗罗 (luozhiwen.com)
Skynet源码之:模块加载(8)
已完成《Skynet源码之:模块加载》
Skynet源码之:模块加载(8) | 不是罗罗 (luozhiwen.com)
Skynet源码之:定时器(9)
已完成《Skynet源码之:定时器》
Skynet源码之:定时器(9) | 不是罗罗 (luozhiwen.com)
Skynet源码之:监视器(10)
已完成《Skynet源码之:监视器》
Skynet源码之:监视器(10) | 不是罗罗 (luozhiwen.com)
Skynet源码之:网络模块(11)
未完成《Skynet源码之:网络模块》
Skynet源码之:网络模块(11) | 不是罗罗 (luozhiwen.com)
Skynet源码之:性能监控(12)
已完成《Skynet源码之:性能监控》
Skynet源码之:性能监控(12) | 不是罗罗 (luozhiwen.com)
Skynet源码之:日志打印(13)
已完成《Skynet源码之:日志打印》
Skynet源码之:日志打印(13) | 不是罗罗 (luozhiwen.com)
Skynet源码之:服务实现(14)
已完成《Skynet源码之:服务实现》
Skynet源码之:服务实现(14) | 不是罗罗 (luozhiwen.com)
Skynet源码之:进程启动(15)
已完成《Skynet源码之:进程启动》
Skynet源码之:进程启动(15) | 不是罗罗 (luozhiwen.com)
Skynet源码之:service_logger(16)
已完成《Skynet源码之:service_logger》
Skynet源码之:service_logger(16) | 不是罗罗 (luozhiwen.com)
Skynet源码之:service_snlua(17)
已完成《Skynet源码之:service_snlua》
Skynet源码之:service_snlua(17) | 不是罗罗 (luozhiwen.com)
Skynet源码之:service_harbor(18)
已完成《Skynet源码之:service_harbor》
Skynet源码之:service_harbor(18) | 不是罗罗 (luozhiwen.com)
Skynet源码之:service_gate(19)
未完成
Skynet专题学习
Skynet专题之:信号
已完成《Skynet专题之:信号》
Skynet专题之:信号| 不是罗罗 (luozhiwen.com)
Skynet专题之:原子操作
已完成《Skynet专题之:原子操作》
Skynet专题之:原子操作| 不是罗罗 (luozhiwen.com)
Skynet专题之:锁
已完成《Skynet专题之:锁》
Skynet专题之:锁| 不是罗罗 (luozhiwen.com)
Skynet专题之:线程
已完成《Skynet专题之:线程》
Skynet专题之:线程| 不是罗罗 (luozhiwen.com)
Skynet专题之:算法
半完成《Skynet专题之:算法》
Skynet专题之:算法| 不是罗罗 (luozhiwen.com)
Skynet接口分析
Skynet接口之:API
skynet.pcall 、skynet.require 的问题
skynet.init by hongling0 · Pull Request #1322 · cloudwu/skynet (github.com)
Skynet相关使用
Skynet使用之:c服务
重点关注service-src目录和cservice目录,以及如何编写自己的c服务
Skynet使用之:c-lua接口和so动态库
主要是学习c-lua如何交互数据
重点关注lublib-src目录和lubclib目录
已完成《Skynet使用之:c-lua接口和so动态库》
Skynet使用之:c-lua接口和so动态库| 不是罗罗 (luozhiwen.com)
Skynet使用之:lua库
lua层的库实现,重点关注lualib目录
Skynet使用之:config配置
关于框架的配置规则以及如何在真实项目中进行配置
Skynet使用之:console控制台
关于console控制台的实现以及使用,如何添加自己的所需要的信息
Skynet使用之:cluster集群
关于框架集群的设计和使用,注意坑点等
Skynet使用之:coroutine协程
了解协程在框架中的实现和使用,以及跟原生的协程的不同
Skynet使用之:sharedata数据共享
已完成《Skynet使用之:sharedata数据共享》
Skynet使用之:sharedata数据共享| 不是罗罗 (luozhiwen.com)
Skynet使用之:codecache代码共享
了解框架是如何实现代码共享,减少代码内存的
Skynet第三方
Skynet第三方之:lz4压缩
主要是lz4的使用,用于压缩游戏中的配置文件
已完成《Skynet第三方之:lz4压缩》
Skynet第三方之:lz4压缩| 不是罗罗 (luozhiwen.com)
Skynet第三方之:sproto协议
主要是sproto的原理和使用,测试使用项目中examples/proto.lua文件
已完成《Skynet第三方之:sproto协议》
Skynet第三方之:sproto协议| 不是罗罗 (luozhiwen.com)
Skynet第三方之:zlog日志
主要是关于zlog的编译,配置和接入使用
已完成《Skynet第三方之:zlog日志》
Skynet第三方之:zlog日志| 不是罗罗 (luozhiwen.com)
Skynet第三方之:mongoDB
主要关于mongoDB的驱动和使用封装
Skynet第三方之:redis
主要关于redis的驱动和使用封装
Skynet第三方之:http/https
主要关于http/https在框架中的使用,有关Skynet开启TLS_MODULE 和 使用skynet.https的问题
Skynet第三方之:lua-xxx工具
相关的lua版本的工具: lua-json、lua-https、lua-cURL