游戏开发论坛

 找回密码
 立即注册
搜索
查看: 6367|回复: 3

关于hotfix

[复制链接]

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20468
发表于 2012-3-30 16:21:00 | 显示全部楼层 |阅读模式
作者:Code@Pig

hotfix, 热更新, 热部署, 动态代码更新


对运行中的系统,实时地替换某个模块(某个函数)的代码。


关于C/C++
对于 C/C++,函数入口在编译后,固定为一段内存地址。想要hotfix,则需要“每次调用此函数,先通过func_map做一个查表”这样来做到。
比如:
void foo();
func_map["foo"] = foo;


void bar()
{
    myfoo = func_map["foo"];
    myfoo();
}


将 foo() 函数放在独立DLL中,更新此DLL文件,然后通知主程序重新load此DLL,并更新func_map,则达到了动态修改代码的目的。
这是根据原理推导出来的方法,但我未在项目中实际用过。


关于脚本语言(lua/python)
来说说脚本语言的hotfix,这是我们每天都要用到的功能。
脚本中跨模块调用,都是“查表找到具体的函数,再调用之”的方式(所以才动态嘛),很适合来做 hotfix


关于python
编辑 foo.py 文件
class Foo(object):
  def gogo(self):
    print 'Foo.gogo 111'


>> import foo
>> f = foo.Foo()
>> f.gogo()
Foo.gogo 111


修改 foo.py
class Foo(object):
  def gogo(self):
    print 'Foo.gogo 222'


>> reload(foo)
>> f.__class__ = foo.Foo
>> f.gogo()
Foo.gogo 222


这里要注意,要hotfix生效,不要直接引用 instance 的 class method,比如:
>> callback = f.gogo
>> callback()
Foo.gogo 222


修改 foo.py
class Foo(object):
  def gogo(self):
    print 'Foo.gogo 333'


>> reload(foo)
>> callback()
Foo.gogo 222


所以,要这样,才能保证hotfix。
>> callback = lambda: f.gogo()


同理,对于普通函数,也不要用局部变量引用起来
>> foo.somefunc()
>> callback = lambda: foo.somefunc()
>> callback()
不能
>> callback = foo.somefunc
>> callback()


关于lua
lua 没有类的概念,所有的替换,其实就是替换模块中的函数。


编辑 foo.lua
module("foo", package.seeall)


function hello()
     print("hello 111")
end


> require("foo")
> foo.hello()
hello 111


修改 foo.lua
module("foo", package.seeall)


function hello()
     print("hello 222")
end


> package.loaded["foo"] = nil
> require("foo")
> foo.hello()
hello 222


一样的,不要直接引用模块中的函数。
如果通过 metatable 设计了一个类机制,自己考虑好,可以保证更新到位。


hotfix的终极解法(erlang)
以上脚本在设计之初,是没有考虑hotfix的,所以在实践hotfix时,需要写代码同学注意一些问题(不能直接引用模块中的函数)
erlang 这块是彻底解决了这个问题,包括变量都是不能二次赋值的,在并发和热更新方面都无比顺畅。


停止模块执行 => 更换模块代码 => 调用code_change转换模块老的数据 => 恢复模块的执行

58

主题

1437

帖子

2207

积分

金牌会员

Rank: 6Rank: 6

积分
2207
发表于 2012-3-31 17:59:00 | 显示全部楼层

Re:关于hotfix

热更新只有只一个称不上好处的好处,
就是在服务器运行时动态修正bug。
为什么说是说不上好处,因为这样会产生懒惰和依赖。
滋生不负责,先上线,有问题再修正的情绪。
而坏处就有一大堆,进而牵扯进来平时用不上的功能也一大坨。
为了服务器稳定运行,热更新后所做的防御编程又一大坨。
开发新功能又要顾及这类没必要的功能。
唯一的用途就是在服务器调试脚本的时候的时候。
标识每次运行脚本是否都从硬盘重新载入的功能,
最简单的热更新,也足够用。

6

主题

74

帖子

230

积分

中级会员

Rank: 3Rank: 3

积分
230
发表于 2012-3-31 23:04:00 | 显示全部楼层

Re:关于hotfix

没啥用,代码更新了,数据怎么办?

这东西也只能做一定的bug修正,也许给脚本导入函数用比较好

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2012-4-3 22:51:00 | 显示全部楼层

Re:关于hotfix

好,长见识
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-28 17:35

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表