Java GAE上的Spring MVC:缓慢加载时间

Java GAE上的Spring MVC:缓慢加载时间,java,performance,google-app-engine,spring-mvc,Java,Performance,Google App Engine,Spring Mvc,我最近在GoogleAppEngine上部署了一个SpringMVC应用程序,初始加载时间约为7秒。加载应用程序后,应用程序的响应速度非常快。但是,如果应用程序空闲超过1分钟(没有任何流量),则需要GAE重新加载该应用程序,这也需要大约7秒的时间。对于PRD级应用,这是不可接受的。(该应用程序是空的——我甚至还没有使用JPA、Sitemesh、Spring Security等。它只是加载一个包含一些文本的jsp页面。) 到目前为止,修复“加载时间”的唯一“最佳实践”是设置一个cron作业,每分钟

我最近在GoogleAppEngine上部署了一个SpringMVC应用程序,初始加载时间约为7秒。加载应用程序后,应用程序的响应速度非常快。但是,如果应用程序空闲超过1分钟(没有任何流量),则需要GAE重新加载该应用程序,这也需要大约7秒的时间。对于PRD级应用,这是不可接受的。(该应用程序是空的——我甚至还没有使用JPA、Sitemesh、Spring Security等。它只是加载一个包含一些文本的jsp页面。)

到目前为止,修复“加载时间”的唯一“最佳实践”是设置一个cron作业,每分钟点击一次url,从而保持应用程序“加载”。显然,这是一个糟糕的解决方案

那么问题来了:在“响应性”方面,Spring对GAE有什么“最佳实践”吗?既然谷歌和spring正在致力于开发两者之间更好的集成,那么在这个问题上有什么新的进展吗?我找不到任何具体的东西,这就是为什么我在这里问它

专题讨论:

更新

有一个创建保留实例的“票证”,以及“加热”逻辑:

好的,由于缺乏响应,我决定使用cron作业(因为我现在看不到任何其他选项)

这是我正在使用的cron.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
  <cron>
    <url>/keepalive</url>
    <description>Keep the application alive</description>
    <schedule>every 1 minutes</schedule>
  </cron>
</cronentries>
因为您可以使用来避免此延迟。

预热请求在任何实时请求到达新实例之前将应用程序代码加载到该实例中。

GAE开始提供付费服务,您可以随时保留热实例:

始终打开-对于低流量或可变流量的高优先级应用程序,您现在可以通过App Engine的始终打开功能保留实例。“始终打开”是一项每月花费9美元的高级功能,它保留应用程序的三个实例,即使应用程序没有流量,也从不关闭它们。这减轻了加载请求对具有少量或可变流量的应用程序的影响


如果您计划使用GAE,结合预热请求,这是最好的解决方案

出于好奇,为什么cron作业“显然”是一个糟糕的解决方案。它“显然”会变差,但如果它能工作……随着应用程序的增长,初始化所需的时间会增加,因此,如果应用程序需要30秒才能初始化,则1分钟的cron作业将变成30秒的cron作业,等等。仅添加spring安全性将大大增加加载时间。此外,它还为Spring/GAE问题增加了不必要的复杂性,该问题应该得到解决。:)请不要这样做。我读过,不幸的是,没有其他办法!除非我希望我的用户在加载页面之前等待10秒,否则这是保持页面相对“生产就绪”的唯一方法。正如我上面提到的,谷歌正在研究一个解决方案(包括付费和免费)。在创建这个解决方案之前,很多创建java应用程序的人都不太幸运:如果你的“生产”应用程序有一些SLA(服务级别协议)要求,那么你需要考虑比GEE更好的托管解决方案。GAE不保证正常运行时间、响应时间等,尤其是免费帐户。如果你想使用GAE,那么你的用户必须支付等待时间。然而,如果你需要某种可靠性,那么你可能会考虑花一些钱。@Gweebz——GAE的网站上没有提到(或警告)Java应用程序的加载时间可能超过15秒,在大多数情况下,从一个“平台”快速切换到另一个“平台”(如亚马逊)是不可行的。所以那些决定在GAE上开发java应用程序的人没有意识到这个巨大的绊脚石。另外,当我启动这个“线程”时,没有支付“始终打开”实例费用的选项。这只在加载初始实例(需要10秒以上)后生效。

package com.xxxxxxxxxxxxx.web;

import org.slf4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


@Controller
@RequestMapping("/keepalive")
public class KeepAliveController {

    private Logger logger = org.slf4j.LoggerFactory.getLogger(KeepAliveController.class);

    @RequestMapping(method = RequestMethod.GET)
    public void keepAlive() {
        logger.info("I'm alive!");
    }
}