普通程序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、...