1

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

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

Play 中是否提供 Tomcat 的热代码替换功能(或类似功能)?

4

2 回答 2

0

正如评论中所说,Play 被设计为无状态的,因此不需要这样的功能。通过使用会话将您的数据存储在客户端上,并且在重新加载代码后它肯定会可用。play.mvc.Http.Session/play.api.mvc.Session使用防止被密钥操纵的cookies。

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

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

于 2013-08-18T11:50:54.863 回答
0

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

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

像这样的东西:

SomeObject.java

package util;

import java.io.Serializable;

public class SomeObject implements Serializable {
    public String someAttribute;
}

ClassWithStaticState.java

package util;

public class ClassWithStaticState {
    public static SomeObject someStateObject; 
}

StatePreserver.java

package util;

@OnApplicationStop
public class StatePreserver extends Job {

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

状态加载器.java

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;
    }
}

有关这些注释的一些解释,请参见此处http://www.playframework.com/documentation/1.2.3/jobs

实际上,我认为play.cache.Cache在这些示例中,Play 完全可以替代序列化,而不是序列化。

于 2013-12-31T03:09:39.717 回答