skynet熱更新方案
阿新 • • 發佈:2019-01-23
普通程式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這個模組出現了問題,替換單個函式可以這樣做:
如果是替換整個模組,需要這樣新建一個module_new.lua檔案local module = require("module") function module:func() print("module:func() new") end
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、...