Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Playframework 热代码替换是否可用?_Playframework - Fatal编程技术网

Playframework 热代码替换是否可用?

Playframework 热代码替换是否可用?,playframework,Playframework,我来自Tomcat的背景,它有一个很好的特性,叫做“热代码替换”——它可以在运行的web应用程序中替换Java代码,而不会干扰现有的HTTP会话/初始化对象 最近我开始学习Play framework,虽然它确实进行“代码替换”,但它似乎可以重新启动整个应用程序,而不仅仅是替换更改的代码,因此所有Java对象/静态变量/HTTP会话都会丢失 Tomcat的热代码替换功能(或类似功能)在游戏中可用吗?如评论中所述,游戏设计为无状态,因此不需要这样的功能。使用会话将数据存储在客户机上,在重新加载代码

我来自Tomcat的背景,它有一个很好的特性,叫做“热代码替换”——它可以在运行的web应用程序中替换Java代码,而不会干扰现有的HTTP会话/初始化对象

最近我开始学习Play framework,虽然它确实进行“代码替换”,但它似乎可以重新启动整个应用程序,而不仅仅是替换更改的代码,因此所有Java对象/静态变量/HTTP会话都会丢失


Tomcat的热代码替换功能(或类似功能)在游戏中可用吗?

如评论中所述,游戏设计为无状态,因此不需要这样的功能。使用会话将数据存储在客户机上,在重新加载代码后数据肯定可用使用安全的Cookie,以防被秘密密钥操纵

如果在会话中存储数据不适用(因为它的大小或因为它被多个客户端全局使用),请使用。诀窍是使缓存中的任何内容都可以恢复,以防由于某种原因丢失(例如在您的情况下重新启动)

对于缓存中存储的任何数据,都需要制定一个再生策略,以防数据丢失。这一理念是Play背后的基础之一,与JavaEE不同,JavaEE期望会话在其整个生命周期中保持价值

我认为Play(仅适用于1.x branch)无状态的主要原因是避免在服务器中以任何形式使用“会话”状态(http会话、静态变量等),因为我认为这有助于简化可伸缩性,但您可以在客户端的加密cookie中使用“登录”状态(随每个http请求一起发送到服务器),对于身份验证,我认为这就足够了,如果需要用户数据,只需再次查询数据库(对于简单字符串,也可以将它们存储在会话中)

无论如何,如果您想在整个应用程序生命周期中“保留”服务器端的某些全局状态,请使用
@OnApplicationStop
序列化当前状态(静态变量、某些对象)并
@OnApplicationStart
再次加载,此机制与播放开发模式的“代码替换”兼容:)

大概是这样的:

SomeObject.java

package util;

import java.io.Serializable;

public class SomeObject implements Serializable {
    public String someAttribute;
}
package util;

public class ClassWithStaticState {
    public static SomeObject someStateObject; 
}
package util;

@OnApplicationStop
public class StatePreserver extends Job {

    @Override
    public void doJob() throws Exception {
        new ObjectOutputStream(new FileOutputStream("preservedstate.bin")).writeObject(ClassWithStaticState.someStateObject);
    }
}
package util;

@OnApplicationStart
public class StateLoader extends Job {
    @Override
    public void doJob() throws Exception {
        File file = new File("preservedstate.bin");
        SomeObject someObject;
        if (file.exists()) {
            someObject = (SomeObject) new ObjectInputStream(new FileInputStream(file)).readObject();
        } else {
            someObject = new SomeObject();
            someObject.someAttribute = "hey!"; // attribute can be modified at runtime but will be preserved across Play development modifications
        }
        ClassWithStaticState.someStateObject =  someObject;
    }
}
ClassWithStaticState.java

package util;

import java.io.Serializable;

public class SomeObject implements Serializable {
    public String someAttribute;
}
package util;

public class ClassWithStaticState {
    public static SomeObject someStateObject; 
}
package util;

@OnApplicationStop
public class StatePreserver extends Job {

    @Override
    public void doJob() throws Exception {
        new ObjectOutputStream(new FileOutputStream("preservedstate.bin")).writeObject(ClassWithStaticState.someStateObject);
    }
}
package util;

@OnApplicationStart
public class StateLoader extends Job {
    @Override
    public void doJob() throws Exception {
        File file = new File("preservedstate.bin");
        SomeObject someObject;
        if (file.exists()) {
            someObject = (SomeObject) new ObjectInputStream(new FileInputStream(file)).readObject();
        } else {
            someObject = new SomeObject();
            someObject.someAttribute = "hey!"; // attribute can be modified at runtime but will be preserved across Play development modifications
        }
        ClassWithStaticState.someStateObject =  someObject;
    }
}
StatePreserver.java

package util;

import java.io.Serializable;

public class SomeObject implements Serializable {
    public String someAttribute;
}
package util;

public class ClassWithStaticState {
    public static SomeObject someStateObject; 
}
package util;

@OnApplicationStop
public class StatePreserver extends Job {

    @Override
    public void doJob() throws Exception {
        new ObjectOutputStream(new FileOutputStream("preservedstate.bin")).writeObject(ClassWithStaticState.someStateObject);
    }
}
package util;

@OnApplicationStart
public class StateLoader extends Job {
    @Override
    public void doJob() throws Exception {
        File file = new File("preservedstate.bin");
        SomeObject someObject;
        if (file.exists()) {
            someObject = (SomeObject) new ObjectInputStream(new FileInputStream(file)).readObject();
        } else {
            someObject = new SomeObject();
            someObject.someAttribute = "hey!"; // attribute can be modified at runtime but will be preserved across Play development modifications
        }
        ClassWithStaticState.someStateObject =  someObject;
    }
}
StateLoader.java

package util;

import java.io.Serializable;

public class SomeObject implements Serializable {
    public String someAttribute;
}
package util;

public class ClassWithStaticState {
    public static SomeObject someStateObject; 
}
package util;

@OnApplicationStop
public class StatePreserver extends Job {

    @Override
    public void doJob() throws Exception {
        new ObjectOutputStream(new FileOutputStream("preservedstate.bin")).writeObject(ClassWithStaticState.someStateObject);
    }
}
package util;

@OnApplicationStart
public class StateLoader extends Job {
    @Override
    public void doJob() throws Exception {
        File file = new File("preservedstate.bin");
        SomeObject someObject;
        if (file.exists()) {
            someObject = (SomeObject) new ObjectInputStream(new FileInputStream(file)).readObject();
        } else {
            someObject = new SomeObject();
            someObject.someAttribute = "hey!"; // attribute can be modified at runtime but will be preserved across Play development modifications
        }
        ClassWithStaticState.someStateObject =  someObject;
    }
}
有关这些注释的一些解释,请参见此处


实际上,我认为Play没有序列化,而是使用了
Play.cache.cache
来代替这些示例中的序列化

哼。Play被设计为无状态,没有服务器状态。您是否将自己的状态存储在服务器上以进行身份验证?@JulienLafont大多数web程序都有登录过程。使用Tomcat和Java,我再也不用登录就能看到新代码的出现。重装代码时,Play framework似乎完全不保留会话信息。“重装代码时,Play framework似乎完全不保留会话信息”。是的,当类被重新加载时JVM被重置。这通常不是问题,因为游戏被认为是完全无状态的。您可以使用无状态服务器进行登录。一切都在你的饼干里。您是在服务器上存储另一个数据,还是只使用会话机制?使用Tomcat,我的J2EE应用程序可以有任何状态信息(无论是会话信息、静态变量还是任何对象),重新加载的类不会破坏任何状态信息。这种行为(或类似行为)在游戏中可用吗?这是否意味着在代码替换期间/之后没有办法保留静态变量值?这听起来太奇怪了,不可能是真的。如果我的应用程序需要10分钟才能启动,我就不应该再等10分钟,只为Play应用一个小的代码更改。@HowardGuo我只是不知道任何方法。不过仍然有一些方法可以实现——afaik Play可以在Tomcat中运行,是否可以使用它来代替集成的Play服务器?除此之外,10分钟的创业时间听起来也很奇怪。如果可能的话,我会让所有的初始化都变得懒惰,这在缓存方法中起到了很好的作用。当然,也可能是Play不是该架构的合适工具。