解决方法
当您的应用在特定时间段内没有任何请求时,Google App Engine会启动新的JVM来处理请求.从“冷”处理数据存储 – 即在JVM中第一次 – 可能需要相当长的时间,最多5秒.
掌握了数据存储区(通常是PersistenceManager的一个实例)之后,一切都很好(对于JVM的生命周期!).
编辑:
在GAE-Java中启动新的JVM也很慢.阅读http://code.google.com/appengine/docs/java/datastore/overview.html,你会看到他们使用Singleton类来获得PersistenceManagerFactory,因为它们描述了将一个实例化为“昂贵”的操作.
你可以自己测试一下.在GAE-Java上创建一个仅返回“Hello World!”的全新应用程序.你会发现对应用程序的第一个请求需要几秒钟.
添加对PersistenceManagerFactory的请求,您会发现第一个请求需要几秒钟.
编辑编辑:
我现在已经为您的观看乐趣创建了这个测试:
http://stackoverflowanswers.appspot.com/helloworld
您将立即看到“Hello,world 0”或“Hello,world xxxx”,其中xxxx是MS中获取数据存储区处理所需时间的计数.我认为数据存储区中索引的复杂性和数量可能会对获取数据存储区处理所需的时间产生影响,因为它在此应用程序中比在我的其他一些应用程序中更快.
PMF是应用引擎文档中提供的副本的精确副本.
@SuppressWarnings("serial") public class HelloWorldServlet extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse resp) throws IOException { long a = System.currentTimeMillis(); PersistenceManager p = PMF.get().getPersistenceManager(); long b = System.currentTimeMillis() - a; resp.setContentType("text/plain"); resp.getWriter().println("Hello,world "+b); } }
编辑编辑编辑:
我更改了我的代码,以便它为每个请求实例化一个PersistenceManagerFactory,现在它会抛出500个服务器错误,并在日志中:
javax.jdo.JDOFatalUserException:
Application code attempted to create a
PersistenceManagerFactory named
transactions-optional,but one with
this name already exists! Instances
of PersistenceManagerFactory are
extremely slow to create and it is
usually not necessary to create one
with a given name more than once.
Instead,create a singleton and share
it throughout your code. If you
really do need to create a duplicate
PersistenceManagerFactory (such as for
a unittest suite),set the
appengine.orm.disable.duplicate.pmf.exception
system property to avoid this error.
我认为我不需要再提供证据证明在应用程序引擎中获取数据存储区的句柄是缓慢的.