游戏服务器开发中的其中一个难点:隔离性。在C/C++写的服务器中,一行代码中的空指针访问,就会导致整个服务器进程crash。
解决方式是:沙盒机制。
Skynet 的沙盒是利用Lua 实现的, 称为服务 snlua 。
下面重点讲这个沙盒是如何实现的
- Skynet 启动
- 沙盒启动API
- snlua 启动
Skynet 启动
Skynet 启动过程, 主要是启动了一些沙盒服务。
Skynet 配置文件一般是 Config 文件。
按照默认配置,启动时,部分日志如下:
$ ./skynet examples/config
[:01000001] LAUNCH logger
[:01000002] LAUNCH snlua bootstrap
[:01000003] LAUNCH snlua launcher
[:01000004] LAUNCH snlua cmaster
[:01000004] master listen socket 0.0.0.0:2013
[:01000005] LAUNCH snlua cslave
[:01000005] slave connect to master 127.0.0.1:2013
[:01000004] connect from 127.0.0.1:55126 4
[:01000006] LAUNCH harbor 1 16777221
[:01000004] Harbor 1 (fd=4) report 127.0.0.1:2526
[:01000005] Waiting for 0 harbors
[:01000005] Shakehand ready
[:01000007] LAUNCH snlua datacenterd
[:01000008] LAUNCH snlua service_mgr
[:01000009] LAUNCH snlua main
...
第一个启动的服务是 logger ,这个服务在之前已经介绍过了,是用C语言实现的。用来打印日志。
bootstrap 这个配置项关系着 skynet 运行的第二个服务。默认的 bootstrap 配置项为
snlua bootstrap
这意味着,skynet 会启动一个 snlua 沙盒服务,并将 bootstrap 作为参数传给它。
按默认配置,服务会加载 service/bootstrap.lua 作为入口脚本。启动后,这个 snlua 服务同样可以称为 bootstrap 服务。
bootstrap 服务, 会根据配置启动其他系统服务, 其中启动了 launcher 服务。更多细节可以见Bootstrap 。
最后,它启动了 main 服务。 main.lua 就是业务逻辑的入口。
沙盒启动API
Lua代码里, 启动其他沙盒服务有2个API
- skynet.launch
- skynet.newservice
例如,服务 bootstrap 启动服务 launcher