1

無料の Google App Engine を次の Android アプリの Google Cloud Messages のバックエンドとして使用しようとしていますが、サーバーの作成を「終了」すると、無料のフロントエンド インスタンス時間のほぼ 100% が既に使用されています。私が持っている質問は、これを改善できるかどうか、またどのように改善できるかです。

アプリケーションは、cron ジョブから 15 分ごとに呼び出されるサーブレットです。サーブレットは 3 つの RSS フィードをダウンロードして解析し、最後の呼び出し以降に変更があったかどうかを確認し、日付をデータベースに保存します (JDO と memcache、3 回の呼び出し)。最後に実行されたのがいつで、最後の呼び出しが接続された電話にその情報を送信してから変更が発生したかどうかを知ることができます。現在、3 つの電話が接続されており、Google サーバーへの呼び出しは 1 回だけです。サーブレットからデータは返されません。

ここにコードがあります

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 を使用するため、1 回の呼び出し後にキャッシュされます。RSS パーサーは、org.w3c.dom.NodeListおよびを使用する単純なパーサーですjavax.xml.parsers.DocumentBuilder。ログ ファイルによると、同じインスタンスを何日も使用しているため、インスタンスの起動とリソースの使用に問題はありません。サーブレットへの通常の呼び出しは、ログでは次のようになります。

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

次に何を試すかについていくつかのアイデアがあります。要求時間を最小限に抑えるために、RSS ダウンロード呼び出しを非同期に実行してみてください。RSS 解析をバックグラウンド ジョブに移動します。他に何ができますか?フロントエンド時間の 100% を消費せずにこのサーブレットを 24 時間に 100 回呼び出すことができない場合、通常の Web アプリはどのように機能するのでしょうか。

/ヴィクトル

4

1 に答える 1

5

アイドル状態のインスタンスは、シャットダウンする前にしばらくの間ぶらぶらしています。どれくらいの長さかわかりませんが、5分から15分くらいだと思います。実際に 15 分の場合、cron ジョブが 15 分ごとにヒットすると無期限に存続するため、1 日 24 インスタンス時間を使用することになります。

この理論をテストするには、cron ジョブを 30 分ごとに実行するように設定し、インスタンス時間の使用量が半分になるかどうかを確認します。

于 2012-07-24T02:23:53.407 に答える