上文写到在 skynet 进程启动过程中,bootstrap 函数会读取传入的配置文件中 bootstrap 对应的项加载启动脚本,其中 bootstrap 一般的配置为 “snlua bootstrap”, 在执行中实际操作就是启动一个 snlua 服务,启动参数为 bootstrap.
执行步骤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
local skynet = require "skynet"
local harbor = require "skynet.harbor"
local service = require "skynet.service"
require "skynet.manager" -- import skynet.launch, ...
skynet.start(function()
local standalone = skynet.getenv "standalone"
-- 启动 launcher 服务,为后续的服务启动提供必要基础
local launcher = assert(skynet.launch("snlua", "launcher"))
skynet.name(".launcher", launcher)
-- 读取是否启用了 harbor 模式
local harbor_id = tonumber(skynet.getenv "harbor" or 0)
if harbor_id == 0 then -- 非 harbor 模式
assert(standalone == nil)
standalone = true
skynet.setenv("standalone", "true")
-- 为了兼容 harbor 模式,启动 cdummy 服务,负责拦截对外广播的全局名字变更
local ok, slave = pcall(skynet.newservice, "cdummy")
if not ok then
skynet.abort()
end
skynet.name(".cslave", slave)
else
if standalone then -- 如果是主节点则启动 cmaster 服务
if not pcall(skynet.newservice, "cmaster") then
skynet.abort()
end
end
-- 不管是不是主节点,都有一个 cslave 服务
local ok, slave = pcall(skynet.newservice, "cslave")
if not ok then
skynet.abort()
end
skynet.name(".cslave", slave)
end
-- 如果是独立启动的话,会启动 datacenterd
if standalone then
local datacenter = skynet.newservice "datacenterd"
skynet.name("DATACENTER", datacenter)
end
-- 启动了 service_mgr 服务
skynet.newservice "service_mgr"
-- 处理 ssl
local enablessl = skynet.getenv "enablessl"
if enablessl then
service.new("ltls_holder", function()
local c = require "ltls.init.c"
c.constructor()
end)
end
-- 调用 config 里的 start 入口服务,默认为 main
pcall(skynet.newservice, skynet.getenv "start" or "main")
skynet.exit()
end)
|
- 启动了 launcher 服务
- 读取 harbor 配置处理 harbor 模式,如果没有使用 harbor 则启动一个 cdummy 服务负责拦截对外广播的全局名字变更,如果使用了 harbor 则在主节点启动 cmaster 服务,并且不管是否主节点都启动 cslave 服务
- 如果是未使用 harbor 的情况下,启动 datacenterd 服务
- 启动 server_mgr 服务
- 如果配置了 enablessl 则会加载 ltls 模块
- 启动配置文件中 start 配置指定的入口服务
launcher 服务
虽然名字是叫 launcher, 但是负责的任务除了启动器的责任还多了一点,主要是给 debug 后台提供一些针对服务的操作接口。比如执行 GC, 查看内存,杀死某个服务之类的。
服务支持两种类型的协议,“lua” 和 “text”, 其中 lua 协议是给 lua 层的各种接口用的,text 的唯一用途是,snlua 启动错误的时候,会给 launcher 发送一个 “ERROR” 消息来报告错误。
绝大部分支持的命令可以参考 wiki 中 DebugConsole 的部分。其余命令中,最常用的,也是 launcher 的本职工作的是 LAUNCH 它负责调用 skynet.launch 启动一个服务,并且把服务的 handle 保存,以备别的服务查询。
datacenterd 服务
datacenterd 只能用来给 harbor 模式下的服务器架构提供一个数据中心的功能。提供的操作支持很有限,会启动在主节点上,并且 cluster 模式下不可用。可以参考 DataCenter 的内容。
- datacenter.get 获取指定 key 的值
- datacenter.set 设置一个键值对
- datacenter.wait 等待一个值被设置,设置后会返回
service_mgr 服务
主要为两个功能提供服务,第一个是 UniqueService, 第二个是 snax. 它会把自己注册成 “.service” 的名字,可以提供全局服务的名字查询和全局服务创建的功能