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

时间:2012-07-23 21:40:06

标签: java performance google-app-engine

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

应用程序是一个servlet,每15分钟从一个cron作业调用,servlet下载并解析3个RSS feed并检查自上次调用以来是否有任何更改,将日期保存到数据库(JDO和memcache,3电话)知道上次运行的时间以及自上次通话以来是否发生了任何变化,将信息发送到已连接的电话,此时已连接3部电话,只需拨打一次谷歌服务器电话。没有从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;
}

调用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下载调用async以最小化请求时间。将RSS解析移动到后台作业。还有什么可以做的?感觉我的代码在这里做了一些基本的错误,因为如果这个servlet在24小时内不能被调用100次而不消耗100%的前端时间,那么普通的web应用程序如何工作呢。

/尤

1 个答案:

答案 0 :(得分:4)

你的闲置实例在关闭之前会暂停一段时间。我不知道这是多久,但我猜它在5-15分钟范围内的某个地方。如果它实际上是15分钟,那么你的cron工作每15分钟就能完成一次,这将使它无限期地保持活力,所以你最终每天会使用24个小时。

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