ウォームアップ要求を構成してパフォーマンスを改善する

ウォームアップ リクエストの目的は、新たに作成されたインスタンスにアプリのコードが読み込まれる過程でリクエストとレスポンスのレイテンシが生じないようにすることにあります。

App Engine は、作成されたばかりのインスタンスにアプリのコードを頻繁に読み込む必要があります。次の場合にインスタンスの読み込みが起こる可能性があります。

  • 別のバージョンのアプリを再デプロイするとき。
  • リクエスト数が現在実行中のインスタンス セットの容量を超え、その不足分を補うために新しいインスタンスが作成されるとき。
  • 基盤となるインフラストラクチャやハードウェアのメンテナンスまたは修復が行われるとき。

アプリのコードを新しいインスタンスに読み込むと、読み込みリクエストが発生することがあります。ユーザーから見えるリクエストのレイテンシが読み込みリクエストのために大きくなる可能性がありますが、ウォームアップ リクエストを使えば、このレイテンシを生じないようにすることができます。ウォームアップ リクエストは、実際のリクエストがインスタンスに到達するよりも先にアプリのコードを新しいインスタンスに読み込みます

アプリケーションでウォームアップ リクエストが有効化されていると、App Engine は新しいインスタンスがアプリケーションで必要になるタイミングを検知し、ウォームアップ リクエストを開始して新しいインスタンスを初期化しようとします。しかし、この検知がいつもうまくいくとは限りません。アプリでウォームアップ リクエストが有効化されていても読み込みリクエストが発生するケースがあります。たとえば、現在トラフィックを処理していないアプリに対する最初のリクエストは必ず読み込みリクエストであり、ウォームアップ リクエストとはなりません。

App Engine アプリケーションに対する他のリクエストと同様、ウォームアップ リクエストもインスタンス時間を消費します。ウォームアップ リクエストが有効になっていても、読み込みリクエストの代わりにウォームアップ リクエストでアプリケーションの初期化が行われているだけなので、ほとんどの場合インスタンス時間が増えていることには気づきません。ウォームアップ リクエスト中に事前キャッシングなど他の処理も行うと、インスタンス時間が増える可能性があります。アイドル インスタンスの数を最小限に設定すると、それらのインスタンスの初回開始時にウォームアップ リクエストが発生することがありますが、それ以降はそれらのインスタンスを引き続き利用できます。

デフォルトのウォームアップ リクエストでは、すべての JAR ファイルがメモリ内のインデックスに登録され、アプリケーションとフィルタが初期化されます。

ウォームアップ リクエストを有効にする

ウォームアップ リクエストは、App Engine スケジューラによって使用されます。このスケジューラはユーザーが指定した構成に基づいてインスタンスの自動スケーリングを制御します。App Engine の Java ランタイムでは、ウォームアップ リクエストがデフォルトで有効になっているため、App Engine が /_ah/warmup に対して GET リクエストを発行することで、必要に応じてレスポンスを返し、アプリケーションのコードを初期化できます。ウォームアップ リクエストは、次のいずれかの方法で処理できます。

<load-on-startup> サーブレットを使用する
ウォームアップ ロジックを追加する最も簡単な方法は、web.xml 設定ファイルで独自のサーブレットを <load-on-startup> として指定する方法です。
ServletContextListener を使用する
ウォームアップ リクエストまたは読み込みリクエストでサーブレットが最初に呼び出される前に、カスタム ロジックを実行できます。
カスタム ウォームアップ サーブレットを使用する
カスタム ウォームアップ サーブレットを使用すると、読み込みリクエストではなくウォームアップ リクエストの場合にのみ、サーブレットの service メソッドが呼び出されます。

選択した方法によっては、/_ah/warmup に独自のハンドラを実装する必要があります。

始める前に

ウォームアップ リクエストが有効になっている場合、さらに多くのインスタンスが必要であると判断すると、スケジューラはインスタンスを起動します。スケジューラはウォームアップ リクエストを使用してアプリを起動するため、アプリでそのリクエストが処理されていなくても、ログには表示されます。

ウォームアップ リクエストは必ず呼び出されるとは限りません。代わりに読み込みリクエストが送信されることがあります。たとえば、インスタンスが初めて起動されるインスタンスである場合や、トラフィックが急激に上昇する場合は、そのようになります。ただし、ウォームアップ リクエストが有効になっている場合、すでにウォームアップされているインスタンスにリクエストを送信する「ベスト エフォート型」のリクエストが試されます。

Java では、ウォームアップ リクエストがデフォルトで有効になっています。有効にするには、appengine-web.xmlinbound_services ディレクティブに - warmup を追加します。ウォームアップはデフォルトで有効になるため、明示的に有効化する必要があるのは、appengine-web.xml でウォームアップ リクエストを無効にしてアプリケーションをデプロイした場合に限られます。このような場合は、<warmup-requests-enabled> 値を true に設定してから再デプロイする必要があります。

<load-on-startup> サーブレットを使用する

ウォームアップ ロジックを実現するのに最も簡単な方法は、独自のサーブレットを web.xml<load-on-startup> と指定することです。この方法の場合、アプリケーション コードを変更する必要がなく、アプリケーションで初期化するときに、指定したすべてのサーブレットが初期化されます。

web.xml ファイルで、起動時に読み込むサーブレットの <servlet> 要素に <load-on-startup>1</load-on-startup> 要素を追加します。次に例を示します。

<servlet>
  <servlet-name>my-servlet</servlet-name>
  <servlet-class>com.company.MyServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

このコードでは、指定したサーブレット クラスを読み込み、サーブレットの init() メソッドを呼び出しています。ウォームアップ リクエストにより、実際のリクエストを処理する前に、指定したサーブレットが初期化されます。ただし、ウォームアップ リクエストがない場合、<load-on-startup> に指定したサーブレットは、新しいインスタンスへの最初のリクエストに登録され、それによってリクエストが読み込まれます。前述のように、App Engine は、アプリケーションが新しいインスタンスを必要とするたびにウォームアップ リクエストを発行するとは限りません。

ServletContextListener を使用する

サーブレットの呼び出し前に実行する必要があるカスタム ロジックがある場合は、次のようにします。

  1. web.xml ファイルに ServletContextListener を登録します。

    <listener>
      <listener-class>com.company.MyListener</listener-class>
    </listener>
    
  2. クラス、サーブレット、フィルタコードを指定します。

    public class MyListener implements ServletContextListener {
      public void contextInitialized(ServletContextEvent event) {
        // This will be invoked as part of a warmup request, or
        // the first user request if no warmup request was invoked.
      }
      public void contextDestroyed(ServletContextEvent event) {
        // App Engine does not currently invoke this method.
      }
    }
    

ServletContextListener は、ウォームアップ リクエストで実行されます。ウォームアップ リクエストがない場合は、新しいインスタンスへの最初のリクエスト時に実行されます。これにより、読み込みリクエストが発生する場合があります。

カスタム ウォームアップ サーブレットを使用する

カスタム ウォームアップ サーブレットは、ウォームアップ リクエスト中にのみ、サーブレットの service メソッドを呼び出します。カスタム ウォームアップ サーブレットに負荷の高いロジックを含めることで、読み込みリクエストでの読み込み時間の増加を回避できます。

カスタム ウォームアップ サーブレットを作成するには、web.xml_ah_warmup の組み込みサーブレット定義を上書きします。

<servlet>
  <servlet-name>_ah_warmup</servlet-name>
  <servlet-class>com.company.MyWarmupServlet</servlet-class>
</servlet>
このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Java の App Engine スタンダード環境