skynet源码分析(三)bootstrap 服务详解

  上文写到在 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)
  1. 启动了 launcher 服务
  2. 读取 harbor 配置处理 harbor 模式,如果没有使用 harbor 则启动一个 cdummy 服务负责拦截对外广播的全局名字变更,如果使用了 harbor 则在主节点启动 cmaster 服务,并且不管是否主节点都启动 cslave 服务
  3. 如果是未使用 harbor 的情况下,启动 datacenterd 服务
  4. 启动 server_mgr 服务
  5. 如果配置了 enablessl 则会加载 ltls 模块
  6. 启动配置文件中 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” 的名字,可以提供全局服务的名字查询和全局服务创建的功能

Licensed under CC BY-NC-SA 4.0
Built with Hugo
主题 StackJimmy 设计