我有一个GWT + GAE网络应用程序,包含多个服务和模块。我正在使用mvp4g的模块functionlity。我的所有服务都延伸:
public abstract class BaseServiceImpl extends RemoteServiceServlet {
protected final static Map USERS = new HashMap();
我使用 USERS 来存储我当前的活跃用户会话。一旦我用户验证自己,我将他的会话ID存储为地图的关键字。
protected String getSessionId() {
return getThreadLocalRequest().getSession().getId();
}
public String authenticate(String username, String password) {
...
..
.
String id = getSessionId();
synchronized( this ) {
users.put(id, user);
}
...
..
.
对于每个请求,我都会检查用户会话是否仍然有效。
protected boolean validUserSession() {
if(getThreadLocalRequest() == null) {
logger.log(Level.SEVERE, "Thread is null");
return false;
} else if(getThreadLocalRequest().getSession() == null) {
logger.log(Level.SEVERE, "Session is null");
return false;
}
String id = getSessionId();
UserJDO user = (UserJDO) users.get(id);
if(user==null) {
logger.log(Level.SEVERE, "User is null");
return false;
}
return true;
}
我启用了会话。接下来,我发布appengine-web.xml的最后几行
...
..
.
<sessions-enabled>true</sessions-enabled>
</appengine-web-app>
开发服务器中的一切正常。但是,当我将其部署到Google应用引擎云时,会为每个请求重置用户变量。
任何人都可以解释一下它发生了什么吗?我该怎么办?我应该将用户会话存储在数据存储区吗?
答案 0 :(得分:6)
在GAE中,每个请求可能会遇到不同的服务器。此外,您的应用程序可能会在每次请求之前被取消部署并重新部署。你不应该依赖静态变量。将您的状态保存在会话或数据库中。
以下是http://code.google.com/appengine/docs/java/runtime.html
的引用App Engine使用多个Web服务器来运行您的应用程序,并自动调整用于可靠处理请求的服务器数量。给定的请求可能被路由到任何服务器,并且它可能与处理来自同一用户的先前请求的服务器不同。
一旦enable sessions,它们会在请求结束时自动存储到数据存储区。
答案 1 :(得分:2)
Google App Engine可以在不同的服务器上运行每个请求。它们不保证在同一台机器上由同一个VM实例提供服务请求。您需要将用户信息存储在持久性存储中,例如BigTable表。