Commit 5e5d76803222a5b31e1481ceb4102a1736bb4937

Authored by zhouhaihai
1 parent 3fe4471e

热更新 优化

src/actions/GmAction.lua
@@ -15,6 +15,9 @@ function _M.clientRequest(agent, data) @@ -15,6 +15,9 @@ function _M.clientRequest(agent, data)
15 return true 15 return true
16 end 16 end
17 17
  18 +function _M.testhotfix(role, pms)
  19 + return csvdb["itemCsv"][1]["name"]
  20 +end
18 21
19 function _M.hero(role, pms) 22 function _M.hero(role, pms)
20 local heroType = tonum(pms.pm1) 23 local heroType = tonum(pms.pm1)
src/actions/HttpAction.lua
@@ -5,61 +5,64 @@ local codecache = require "skynet.codecache" -- 清空缓存用 @@ -5,61 +5,64 @@ local codecache = require "skynet.codecache" -- 清空缓存用
5 5
6 local _M = {} 6 local _M = {}
7 7
8 --- 清空代码和csvdata 缓存 (无论什么热更新 都要先更新服务器 然后调用这个 api 再进行更新) 8 +-- 清空缓存
9 function _M.clearcache(query, body) 9 function _M.clearcache(query, body)
10 skynet.error(string.format("clearcache time: %s", skynet.timex())) 10 skynet.error(string.format("clearcache time: %s", skynet.timex()))
11 codecache.clear() 11 codecache.clear()
12 return 'success' 12 return 'success'
13 end 13 end
14 14
15 ---重新加载 csvdata -- 需要先调用 clearcache 15 +--重新加载 需要修改的csvdb
  16 +--[=[ eg:
  17 + body = """
  18 + csvdb["itemCsv"][1]["name"] = "测试一下"
  19 + """
  20 +]=]
  21 +
16 function _M.reload_csvdata(query, body) 22 function _M.reload_csvdata(query, body)
17 - skynet.error(string.format("reload_csvdata time: %s", skynet.timex()))  
18 - local status = skynet.call('CSVDATA', "lua", "reload")  
19 - if status == "ok" then  
20 - -- 所有需要 更新的服务 都更新一下数据  
21 - pcall(skynet.call, 'WATCHDOG', "lua", "reloadCsvData")  
22 - pcall(skynet.call, 'NGXD', "lua", "reloadCsvdb") 23 + if not body or body == "" then
  24 + return
23 end 25 end
24 - return 'success'  
25 -end  
26 26
27 ---post 需要更改的 globalCsv json  
28 -function _M.global_csv(query, body)  
29 - if not body or body == "" then return end  
30 - local change = json.decode(body) -- json 表  
31 - if not next(change) then return end  
32 - skynet.error(string.format("global_csv change time: %s, value: %s", skynet.timex(), body))  
33 - -- 更新所有需要更新globalDefine 的地方  
34 - pcall(skynet.call, 'WATCHDOG', "lua", "reloadCsvData", change)  
35 - pcall(skynet.call, 'NGXD', "lua", "reloadCsvdb", change) -- 他也要改 27 + local ok = pcall(load, body)
  28 + if not ok then return end
36 29
37 - return 'success' 30 + skynet.error(string.format("reload_csvdata time: %s, code: %s", skynet.timex(), body))
  31 +
  32 + local status = skynet.call('CSVDATA', "lua", "reload", body)
  33 + if status == "ok" then
  34 + return 'success'
  35 + end
38 end 36 end
39 37
40 38
41 -- 热更新代码 -- 针对 agent 执行发送过来的代码 -- 代码要规范~ 39 -- 热更新代码 -- 针对 agent 执行发送过来的代码 -- 代码要规范~
42 40
43 --[=[ eg: 41 --[=[ eg:
44 -1. *Action 重新加载 (action 每次用才require 直接清掉重新加载) (某些)  
45 - body = "package.loaded['actions.*Action']=nil" 42 +1. *Action
  43 + body = """
  44 + _hotfixActions = _hotfixActions or {}
  45 + _hotfixActions["Gm.clientRequest"] = function(agent, data)
  46 + bin = MsgPack.pack({ cmd = "testtest" })
  47 + SendPacket(actionCodes.Gm_receiveResponse, bin)
  48 + end
  49 + """
46 50
47 2. 修改 global 方法 和 变量 直接覆盖 51 2. 修改 global 方法 和 变量 直接覆盖
48 body = """ 52 body = """
49 function a() 53 function a()
50 print(123) 54 print(123)
51 end 55 end
  56 +
  57 + globalCsv["asdasd"] = 12
  58 +
  59 + HEHE = 123
52 """ 60 """
53 61
54 -3. 修改 role 方法 62 +3. 修改 role 方法(待定)
55 63
56 body = """ 64 body = """
57 - local role = ...  
58 - if role then  
59 - role.getItemCount = function(self)  
60 - return "hehe"  
61 - end  
62 - end 65 +
63 """ 66 """
64 ]=] 67 ]=]
65 68
@@ -67,9 +70,11 @@ function _M.hotfix(query, body) @@ -67,9 +70,11 @@ function _M.hotfix(query, body)
67 if not body or body == "" then 70 if not body or body == "" then
68 return 71 return
69 end 72 end
70 - skynet.error(string.format("hotfix time: %s, code: %s", skynet.timex(), body))  
71 local ok = pcall(load, body) 73 local ok = pcall(load, body)
72 if not ok then return end 74 if not ok then return end
  75 +
  76 + skynet.error(string.format("hotfix time: %s, code: %s", skynet.timex(), body))
  77 +
73 pcall(skynet.call, 'WATCHDOG', "lua", "hotfix", body) 78 pcall(skynet.call, 'WATCHDOG', "lua", "hotfix", body)
74 return 'success' 79 return 'success'
75 end 80 end
@@ -16,12 +16,15 @@ skynet = require "skynet" @@ -16,12 +16,15 @@ skynet = require "skynet"
16 redisproxy = require "shared.redisproxy" 16 redisproxy = require "shared.redisproxy"
17 datacenter = require "skynet.datacenter" 17 datacenter = require "skynet.datacenter"
18 mcast_util = require "services/mcast_util" 18 mcast_util = require "services/mcast_util"
  19 +globalCsv = require "csvdata/GlobalDefine"
19 20
20 local CMD = {} 21 local CMD = {}
21 local agentInfo = {} -- { client_fd, role, gate_serv, open_timer} 22 local agentInfo = {} -- { client_fd, role, gate_serv, open_timer}
22 23
23 local agent_util, cs 24 local agent_util, cs
24 25
  26 +_hotfixActions = _hotfixActions or {}
  27 +
25 --- {{{ 定时器相关 28 --- {{{ 定时器相关
26 local function handle_timeout() 29 local function handle_timeout()
27 if not agentInfo.open_timer then return end 30 if not agentInfo.open_timer then return end
@@ -183,16 +186,21 @@ skynet.register_protocol { @@ -183,16 +186,21 @@ skynet.register_protocol {
183 print("actionName not exist", actionName) 186 print("actionName not exist", actionName)
184 return 187 return
185 end 188 end
186 - local modName, funcName = actionName:match("(%w+)%.(%w+)")  
187 189
188 - local ok, action = pcall(require, "actions." .. modName .. "Action")  
189 - if not ok then  
190 - print("require module name error", action, modName)  
191 - return 190 + local method
  191 + if _hotfixActions[actionName] then
  192 + method = _hotfixActions[actionName]
  193 + else
  194 + local modName, funcName = actionName:match("(%w+)%.(%w+)")
  195 +
  196 + local ok, action = pcall(require, "actions." .. modName .. "Action")
  197 + if not ok then
  198 + print("require module name error", action, modName)
  199 + return
  200 + end
  201 + method = action[funcName]
192 end 202 end
193 -  
194 - local method = action[funcName]  
195 - 203 +
196 if type(method) ~= "function" then 204 if type(method) ~= "function" then
197 print("ERROR_SERVER_INVALID_ACTION", modName, funcName) 205 print("ERROR_SERVER_INVALID_ACTION", modName, funcName)
198 return 206 return
@@ -226,7 +234,7 @@ skynet.register_protocol { @@ -226,7 +234,7 @@ skynet.register_protocol {
226 } 234 }
227 235
228 -- function CMD.start(gate, fd, ip) 236 -- function CMD.start(gate, fd, ip)
229 -function CMD.start(session, source, gate, fd, ip) 237 +function CMD.start(session, source, gate, fd, ip, hotfixs)
230 ignoreHeartbeat = false 238 ignoreHeartbeat = false
231 239
232 agentInfo.client_fd = fd 240 agentInfo.client_fd = fd
@@ -236,10 +244,9 @@ function CMD.start(session, source, gate, fd, ip) @@ -236,10 +244,9 @@ function CMD.start(session, source, gate, fd, ip)
236 agent_util:reset() 244 agent_util:reset()
237 math.randomInit() 245 math.randomInit()
238 246
239 -  
240 - -- 这里加载配表 不然热更新对某些 agent 无效  
241 - csvdb = sharedata.query("csvdata")  
242 - globalCsv = require "csvdata/GlobalDefine" 247 + for _, hotfix in ipairs(hotfixs) do
  248 + CMD.hotfix(hotfix)
  249 + end
243 250
244 -- 这里将消息伪装成 watchdog 发出,这样就由 A->B->C->B->A 变成 A->B->C->A 251 -- 这里将消息伪装成 watchdog 发出,这样就由 A->B->C->B->A 变成 A->B->C->A
245 skynet.redirect(gate, source, "lua", session, skynet.pack("forward", fd, 0, skynet.self())) 252 skynet.redirect(gate, source, "lua", session, skynet.pack("forward", fd, 0, skynet.self()))
@@ -274,20 +281,10 @@ function CMD:usubUnion() @@ -274,20 +281,10 @@ function CMD:usubUnion()
274 agentInfo.userv = nil 281 agentInfo.userv = nil
275 end 282 end
276 283
277 -function CMD.reloadCsvdb(globalData)  
278 - if globalData then  
279 - for k, v in pairs(globalData) do  
280 - globalCsv[k] = v  
281 - end  
282 - else  
283 - csvdb = sharedata.query("csvdata")  
284 - end  
285 -end  
286 -  
287 function CMD.hotfix(code) 284 function CMD.hotfix(code)
288 local ok, func = pcall(load, code) 285 local ok, func = pcall(load, code)
289 if ok then 286 if ok then
290 - ok = pcall(func, agentInfo.role) 287 + ok = pcall(func)
291 end 288 end
292 if not ok then 289 if not ok then
293 skynet.error("hotfix error by code " .. code) 290 skynet.error("hotfix error by code " .. code)
@@ -328,6 +325,7 @@ skynet.start(function() @@ -328,6 +325,7 @@ skynet.start(function()
328 325
329 cs = queue() 326 cs = queue()
330 327
  328 + csvdb = sharedata.query("csvdata")
331 -- 错误码特殊处理 329 -- 错误码特殊处理
332 -- todo 330 -- todo
333 -- for key, value in pairs(csvdb["sys_codesCsv"]) do 331 -- for key, value in pairs(csvdb["sys_codesCsv"]) do
src/services/agent_ctrl.lua
@@ -132,13 +132,10 @@ function _M:check_agent_status() @@ -132,13 +132,10 @@ function _M:check_agent_status()
132 end 132 end
133 end 133 end
134 134
135 -function _M:reload_csvdata(globalData)  
136 - for uid, pack in pairs(self.u2f) do  
137 - local agent = get_a(pack)  
138 - pcall(skynet.send, agent, "lua", "reloadCsvdb", globalData)  
139 - end  
140 -end 135 +local hotfixList = {}
  136 +
141 function _M:hotfix(code) 137 function _M:hotfix(code)
  138 + table.insert(hotfixList, code)
142 for uid, pack in pairs(self.u2f) do 139 for uid, pack in pairs(self.u2f) do
143 local agent = get_a(pack) 140 local agent = get_a(pack)
144 pcall(skynet.send, agent, "lua", "hotfix", code) 141 pcall(skynet.send, agent, "lua", "hotfix", code)
@@ -193,7 +190,7 @@ function _M:query_agent(fd, uid) @@ -193,7 +190,7 @@ function _M:query_agent(fd, uid)
193 return 190 return
194 end 191 end
195 192
196 - local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, fd, self.f2i[fd]) 193 + local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, fd, self.f2i[fd], hotfixList)
197 if not ok then 194 if not ok then
198 self.factory:push(agent) 195 self.factory:push(agent)
199 query_agent_response(fd, {ret = "INNER_ERROR"}) 196 query_agent_response(fd, {ret = "INNER_ERROR"})
src/services/csvdatad.lua
@@ -61,19 +61,20 @@ end @@ -61,19 +61,20 @@ end
61 61
62 62
63 local CMD = {} 63 local CMD = {}
64 -function CMD.reload() 64 +function CMD.reload(code)
65 -- 重新加载 csvdata 65 -- 重新加载 csvdata
66 - csvdb = {}  
67 - for k, v in pairs(package.loaded) do  
68 - if k:find("csvdata") then  
69 - package.loaded[k] = nil  
70 - end 66 + csvdb = csvdb or {}
  67 +
  68 + local ok, func = pcall(load, code)
  69 + if ok then
  70 + ok = pcall(func)
  71 + end
  72 + if not ok then
  73 + skynet.error("reload_csvdata error by code " .. code)
  74 + return 'error'
71 end 75 end
72 - require("csvdata.init")  
73 - require("csvdata.init_adv")  
74 76
75 sharedata.update("csvdata", csvdb) 77 sharedata.update("csvdata", csvdb)
76 - skynet.sleep(1) -- 睡一觉再返回  
77 return 'ok' 78 return 'ok'
78 end 79 end
79 80
src/services/httpweb.lua
@@ -9,7 +9,7 @@ require "utils.init" @@ -9,7 +9,7 @@ require "utils.init"
9 local table = table 9 local table = table
10 local string = string 10 local string = string
11 11
12 -local port, watchdog = ... 12 +local port = ...
13 port = tonumber(port) 13 port = tonumber(port)
14 14
15 local key = "zhaolu1234dangge" 15 local key = "zhaolu1234dangge"
src/services/ngxd.lua
@@ -93,25 +93,10 @@ local function start() @@ -93,25 +93,10 @@ local function start()
93 end 93 end
94 end 94 end
95 95
96 -local CMD = {}  
97 -function CMD.reloadCsvdb(globalData)  
98 - if globalData then  
99 - for k, v in pairs(globalData) do  
100 - globalCsv[k] = v  
101 - end  
102 - else  
103 - csvdb = sharedata.query("csvdata")  
104 - end  
105 -end  
106 -  
107 -  
108 local function __init__() 96 local function __init__()
109 skynet.dispatch("lua", function(_,_, command, ...) 97 skynet.dispatch("lua", function(_,_, command, ...)
110 if command == "start" then 98 if command == "start" then
111 skynet.ret(skynet.pack(start(...))) 99 skynet.ret(skynet.pack(start(...)))
112 - else  
113 - local f = CMD[command]  
114 - skynet.ret(skynet.pack(f(...)))  
115 end 100 end
116 end) 101 end)
117 102
src/services/watchdog.lua
@@ -89,10 +89,6 @@ function CMD.forceClose(fd) @@ -89,10 +89,6 @@ function CMD.forceClose(fd)
89 agent_ctrl:exit_agent(fd) 89 agent_ctrl:exit_agent(fd)
90 end 90 end
91 91
92 -function CMD.reloadCsvData(globalData)  
93 - agent_ctrl:reload_csvdata(globalData)  
94 -end  
95 -  
96 function CMD.hotfix(code) 92 function CMD.hotfix(code)
97 agent_ctrl:hotfix(code) 93 agent_ctrl:hotfix(code)
98 end 94 end