V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
hunniman
V2EX  ›  问与答

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

  •  
  •   hunniman · 2015-08-01 18:02:11 +08:00 · 5333 次点击
    这是一个创建于 3402 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现准备用java实现游戏服务器,因需要不停服来热更新线上服务器的一些小bug,网上关于java热更新文章比较少,看了下java 6的 javaagent貌似能实现,不知道哪位大神有做过类似功能。
    4 条回复    2015-08-02 02:20:59 +08:00
    wohenyingyu01
        1
    wohenyingyu01  
       2015-08-01 18:31:53 +08:00
    osgi框架
    celon
        2
    celon  
       2015-08-01 18:45:58 +08:00
    用Classloader载入,用此ClassLoader反射响应请求,就好
    MOsky
        3
    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
        4
    SoloCompany  
       2015-08-02 02:20:59 +08:00
    那是叫 hostswap 吧,这东西在线上使用不靠谱吧
    hotswap 要求不能有结构性变化才能成功,结构性变化就是说不能有 class / member / method 的任何变更,也就是说只能有实现变更
    也有比如 jrebel 这样的东西支持结构变更的 hotswap 但感觉更不靠谱了

    建议还是用传统的方式吧,比如 tomcat8 支持的 webapp versioning,也就是说同一个 app 的两个不同版本可以同时上线,新版本上线不影响旧版本的 app 继续为已经在服务中的任务进行处理
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2753 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 06:59 · PVG 14:59 · LAX 22:59 · JFK 01:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.