前端实例小时数 - 如何减少使用量?

Vik*_*tor 1 java performance google-app-engine

我正在尝试使用免费的 Google App Engine 作为我的下一个 Android 应用程序的 Google Cloud Messages 的后端,但是当我“完成”编写服务器时,它已经使用了几乎 100% 的免费前端实例时间。我的问题是我是否以及如何改进这一点?

该应用程序是一个 servlet,从 cron 作业每 15 分钟调用一次,servlet 下载并解析 3 个 RSS 提要并检查自上次调用以来是否有任何更改,将日期保存到数据库(JDO 和 memcache,3 次调用)以知道上次运行是什么时候,以及自上次调用将信息发送到连接的电话后是否发生了任何变化,现在有 3 部电话已连接,这只是对 Google 服务器的一次调用。servlet 不返回任何数据。

这是代码

public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException
{
    boolean sendMessage = false;

    String eventsFeedUrl = "http://rss.com";
    String newsFeedUrl = "http://rss2.com";
    String trafficFeedUrl = "http://rss3.com";

    response.setContentType("text/plain");
    Message.Builder messageBuilder = new Message.Builder();
    String messageData = getFeedMessageData(eventsFeedUrl);
    if (!messageData.equals(StringUtils.EMPTY))
    {
        messageBuilder.addData("event", messageData);
        sendMessage = true;
    }
    messageData = getFeedMessageData(newsFeedUrl);
    if (!messageData.equals(StringUtils.EMPTY))
    {
        messageBuilder.addData("news", messageData);
        sendMessage = true;
    }
    messageData = getFeedMessageData(trafficFeedUrl);
    if (!messageData.equals(StringUtils.EMPTY))
    {
        messageBuilder.addData("traffic", messageData);
        sendMessage = true;
    }
    if (sendMessage)
    {
        sendMessage(messageBuilder.build(), response, debug);
    }
}

private void sendMessage(Message message, HttpServletResponse response, boolean debug)
    throws IOException
{
    SendResult sendResult = GCMService.send(message, Device.list());
    int deleteCount = 0;
    for (MessageResult errorResult : sendResult.getErrorResults())
    {
        if (deleteCount < 200 && (errorResult.getErrorName().equals(Constants.ERROR_NOT_REGISTERED) || errorResult.getErrorName().equals(Constants.ERROR_INVALID_REGISTRATION)))
        {
            Device.delete(errorResult.getDeviceId());
            deleteCount++;
        }
    }
}

private String getFeedMessageData(String feedUrl)
{
    String messageData = StringUtils.EMPTY;
    FeedHistory history = FeedHistory.getFeedHistoryItem(feedUrl);
    Feed feedContent = RssParser.parse(feedUrl);
    if (feedContent != null && feedContent.getFeedItems().size() > 0)
    {
        if (history == null)
        {
            history = new FeedHistory(feedUrl);
            history.setLastDate(new Date(0));
            history.save();
        }
        for (FeedItem item : feedContent.getFeedItems())
        {
            if (item.getDate().after(history.getLastDate()))
            {
                messageData += "|" + item.getCountyId();
            }
        }
        if (!messageData.equals(StringUtils.EMPTY))
        {
            messageData = new SimpleDateFormat("yyyyMMddHHmmssZ").format(history.getLastDate()) + messageData;
        }
        history.setLastDate(feedContent.getFeedItem(0).getDate());
        history.save();
    }
    return messageData;
}
Run Code Online (Sandbox Code Playgroud)

调用 Device.list() 使用 memcache,因此在一次调用后它将被缓存,RSS 解析器是一个简单的解析器,它使用org.w3c.dom.NodeListjavax.xml.parsers.DocumentBuilder。根据日志文件,我使用同一个实例数天,因此实例启动和占用资源没有问题。对 servlet 的正常调用在日志中看起来像这样,

ms=1480 cpu_ms=653 api_cpu_ms=0 cpm_usd=0.019673

我对接下来要尝试的内容有一些想法,尝试异步执行 RSS 下载调用以最小化请求时间。将 RSS 解析移动到后台作业。还能做什么?感觉就像我在这里的代码犯了一些基本错误,因为如果不能在 24 小时内调用该 servlet 100 次而不消耗 100% 的前端时间,那么普通的 Web 应用程序如何工作。

/维克多

dra*_*onx 5

在关闭自己之前,您的空闲实例会停留一段时间。我不知道这是多长时间,但我猜它在 5-15 分钟范围内的某个地方。如果它实际上是 15 分钟,那么您每 15 分钟执行一次 cron 作业将使其无限期地保持活动状态,因此您最终将每天使用 24 个实例小时。

您可以通过将 cron 作业设置为每 30 分钟运行一次来​​测试此理论,看看它是否将您的实例小时使用量减半。