java 游戏服务器怎么实现热更新?

2015-08-01 18:02:11 +08:00
 hunniman
现准备用java实现游戏服务器,因需要不停服来热更新线上服务器的一些小bug,网上关于java热更新文章比较少,看了下java 6的 javaagent貌似能实现,不知道哪位大神有做过类似功能。
5367 次点击
所在节点    问与答
4 条回复
wohenyingyu01
2015-08-01 18:31:53 +08:00
osgi框架
celon
2015-08-01 18:45:58 +08:00
用Classloader载入,用此ClassLoader反射响应请求,就好
MOsky
2015-08-01 23:52:07 +08:00
以前我在游戏公司上班的时候考虑过这个问题。

一种是 Java 有一个什么机制(忘了名字,去网上搜吧)可以在 JVM 运行阶段动态替换类方法的实现。Eclipse 的 debug 模式好像就是用这种方法来允许你调试的时候动态改代码的。

这种模式有个问题,如果是生产服务器用这个热更新的话,比较乱来,不够让人安心。

另一个方案就是如楼上所说的 ClassLoader。

这个方案比上一个方案要安全得多。但是存在两个问题。

1. 比较难管理。Java 无法主动卸载 ClassLoader 实例,只能等实例变成不可达,然后等 GC 清理掉。这要求你清楚的知道 ClassLoader 会被哪些(有一堆乱七八糟的候选项目)对象直接或间接引用。

这必须要求你的服务器业务模块之间藕合度极低(主要是模块之间调用传的参数和返回值必须是Java标准对象,不可直接或间接引用各种需要 ClassLoader 载入的封装对象)。如果做不到,你的生产服务器可能同时运行新旧两种业务代码,就只好哭爹喊娘了。

对于游戏服务器业务,好像很不好写啊。又不是 servlet,servlet 就随随便便热加载。

2. 如果你不幸生产服务器使用的是 Java 6 以及以下版本,那么你可能会遇到方法区内存用光的问题。如果你使用 Java 7 ,那恭喜你,Java 7 的方法区取消了,直接挪堆区,你完全不必关心这个问题。GC 迟早能卸载旧的代码。

最后,这两种方案最终没有一种被弃用。还是按照老方法要更新服务器就重启服务器,全服玩家全部滚下线候着吧。以上只是纸上谈兵。
SoloCompany
2015-08-02 02:20:59 +08:00
那是叫 hostswap 吧,这东西在线上使用不靠谱吧
hotswap 要求不能有结构性变化才能成功,结构性变化就是说不能有 class / member / method 的任何变更,也就是说只能有实现变更
也有比如 jrebel 这样的东西支持结构变更的 hotswap 但感觉更不靠谱了

建议还是用传统的方式吧,比如 tomcat8 支持的 webapp versioning,也就是说同一个 app 的两个不同版本可以同时上线,新版本上线不影响旧版本的 app 继续为已经在服务中的任务进行处理

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/210090

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX