我尝试使用免费的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.NodeList
和javax.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应用程序如何工作呢。
/尤
答案 0 :(得分:4)
你的闲置实例在关闭之前会暂停一段时间。我不知道这是多久,但我猜它在5-15分钟范围内的某个地方。如果它实际上是15分钟,那么你的cron工作每15分钟就能完成一次,这将使它无限期地保持活力,所以你最终每天会使用24个小时。
您可以通过将cron作业设置为每30分钟运行一次来测试此理论,并查看它是否将实例小时数减半。