Skynet 动态控制无状态服务的数量

应用场景: 用于复杂计算的服务,可伸缩的控制服务的数量,比如高峰期到来时开启更多的服务,高峰过后需要回收的服务。

这里只演示无状态的服务,有状态的服务处理更复杂。

  1. 给一堆相同的无状态服务(calculate)用个管理器(calculate_mng)管理起来
  2. calculate_mng 作为入口供其他服务器调用
  3. calculate_mng 对 calculate 服务有生杀大权

如何正确的退出服务?

这里有讲到退出服务的接口 Skynet 服务的启动和退出

skynet.exit() 用于退出当前的服务。skynet.exit 之后的代码都不会被运行。而且,当前服务被阻塞住的 coroutine 也会立刻中断退出。这些通常是一些 RPC 尚未收到回应。所以调用 skynet.exit() 请务必小心。
skynet.kill(address) 可以用来强制关闭别的服务。但强烈不推荐这样做。因为对象会在任意一条消息处理完毕后,毫无征兆的退出。所以推荐的做法是,发送一条消息,让对方自己善后以及调用 skynet.exit 。注:skynet.kill(skynet.self()) 不完全等价于 skynet.exit() ,后者更安全。

为了正确的退出服务,需要选用 skynet.exit(),而且要确保没有挂起的 RPC。

我们这里的例子是无状态服务,服务也比较简单,只做复杂计算,不会再发起 RPC 去其他地方请求数据(比如去数据库读取数据)。所以只需要这样写退出函数就行了。

function CMD.exit()
    skynet.error("slave exit.")
    skynet.ret()
    skynet.exit()
    -- exit() 之后的代码是不会执行的
end

负载均衡?

用数组 slave 把服务的地址存起来,然后在每调用一次计算接口 calculate 就换下一个服务。

local slave = {}
local balance = 1

-- 找一个 slave 帮忙做点复杂的计算
function CMD.calculate(a, b)
    local s = slave[balance]
    balance = balance + 1
    if balance > #slave then
        balance = 1
    end
    return skynet.call(s, "lua", "calculate", a, b)
end

动态伸缩服务数量?

取当前服务的数量 #slave, 数量相同就跳过,服务数量不够就开启新的服务,服务数量多了就干掉多余的服务。

function CMD.set_slave_count(cnt)
    local now_cnt = #slave
    if now_cnt == cnt then
        skynet.error(string.format("slave count is:%d", now_cnt))
        return
    end

    balance = 1
    if now_cnt > cnt then
        local kill_cnt = now_cnt - cnt
        for _=1,kill_cnt do
            local s = slave[#slave]
            skynet.call(s, "lua", "exit")
            table.remove(slave)
        end
        skynet.error(string.format("slave old_cnt:%d, new_cnt:%d", now_cnt, #slave))
        return
    end

    if now_cnt < cnt then
        local add_cnt = cnt - now_cnt
        for _=1,add_cnt do
            table.insert(slave, skynet.newservice(SLAVE_SERVICE_NAME))
        end
        skynet.error(string.format("slave old_cnt:%d, new_cnt:%d", now_cnt, #slave))
        return
    end
end

自动伸缩?

这个我就没写代码了,一般就是用启动心跳定时去监测服务的繁忙情况。

完整代码在这里: Skynet 动态控制无状态服务的数量

点击进入评论 ...