1. 程式人生 > >skynet熱更新方案

skynet熱更新方案

    普通程式lua的熱更新:

    lua的熱更新一般是比較方便的,比如下面一個模組module.lua

local module = {}
function module:func()
    print("module:func()")
end
    通常實現更新會這樣做:

    local old_module = require("module")

    package.loaded["module"] = nil

    local new_module = require("module")

    for k,v in pairs(new_module) do

        old_module[k] = v

    end

    package.loaded["module"]  = old_module

    如果只是函式的更新,那就更容易了,使用dofile或者dostring就可以了。

skynet的熱更新

skynet對熱更新的定位只是一種緊急處理BUG的應急手段,所以並不做整個模組的熱更新機制。另外由於程式碼在多個虛擬機器之間共享機制的存在,上面的方法不會成功。    如果線上的module.lua這個模組出現了問題,替換單個函式可以這樣做:
local module = require("module")
function module:func()
    print("module:func() new")
end
    如果是替換整個模組,需要這樣新建一個module_new.lua檔案
local module = {}
function module:func()
    print("module:func()")
end
    然後新建一個用於更新的檔案patch.lua

 local old_module = require("module")

    package.loaded["module"] = nil

    local new_module = require("module_new")

    for k,v in pairs(new_module) do

        old_module[k] = v

    end

    package.loaded["module"]  = old_module

    在除錯控制檯中執行 inject patch.lua

    這種方式在更新一般服務時,可以滿足需求。

    但是在像agent這種會新生成的服務,老的更新程式碼不起作用。要實現新的服務更新可以使用下面幾種方式

    1、將需要更新的程式碼製作成patch.lua,更新時將更新內容註冊到agent管理器中,新生成agent時,通知agent進行程式碼更新。
    2、需要進行熱更新的模組停用程式碼共享機制,這樣新服務生成時,會載入新的模組程式碼

    3、...