Java 8 ランタイム環境

App Engine を使用すると、Google のスケーラブルなインフラストラクチャとサービスを使用するウェブ アプリケーションをビルドできます。App Engine は Java 8 JVM を使用してウェブ アプリケーションを実行します。また、アプリケーションのサーブレット クラスを呼び出して、この環境でリクエストの処理とレスポンスの準備を行います。

App Engine プラットフォームには、コードから呼び出せる多数の組み込み API サービスが用意されています。また、アプリケーションでは、指定の間隔で実行されるタスクのスケジュールを構成することもできます。

アプリ用の Java 8 ランタイムの指定

アプリで Java 8 ランタイムを使用するには、以下の行を appengine-web.xml ファイルに追加します。

<runtime>java8</runtime>

このように変更するだけで、現在 Java 7 ランタイムを使用している既存の App Engine アプリケーションは、Java 8 ランタイムで実行されるようになります。

Java 8 ランタイムの拡張機能とアップグレード

OpenJDK 8 に基づく App Engine Java 8 ランタイムでは、現在の Java 7 ランタイムで使用可能な既存の機能がすべてサポートされています。これは OpenJDK 7 に基づいていますが、それに加えて以下のアップグレードと拡張があります。

  • Java 7 ランタイムのようにセキュリティ マネージャーが使用されないため、コードは Java の権限によって制限されません。
  • 標準の公開 Java ライブラリのすべてをサポートします。
  • Jetty 9 を使用します。
  • Java サーブレット 3.1 と Java サーブレット 2.5 仕様をサポートします。
  • Java 用 Google Cloud クライアント ライブラリからアクセス可能な Google Cloud ベースの API をすべてサポートします。

はじめに

Java 8 ランタイムの選択

App Engine API for Java は、Cloud SDK の一部として App Engine SDK 付属の appengine-api-*.jar で表されます(ここで、* は API と App Engine SDK のバージョンを表します)。

アプリケーションで使用する API のバージョンを選択するには、この JAR をアプリケーションの WEB-INF/lib/ ディレクトリに配置するか、Maven を使用して依存関係を処理します。リリースされた新しいバージョンの Java ランタイム環境に、既存のアプリケーションと互換性のない変更が導入された場合、この環境には新しいバージョン番号が付与されます。

Maven を使用して依存関係を処理する

Maven を使用してすべての依存関係を管理できます。たとえば、以下の pom.xml エントリには、最新の App Engine API(Maven Central で入手可能な Rappengine-api-1.0-sdk)が含まれています。

<dependency>
    <groupId>com.google.appengine</groupId>
    <artifactId>appengine-api-1.0-sdk</artifactId>
    <version><span class="notranslate exporttrans-dynamic">print setvar.appengine_java_version</span></version>
</dependency>

サンドボックス

App Engine Java ランタイムは、複数のアプリケーションへのリクエストを複数のウェブサーバーに分散し、アプリケーションが相互に干渉しないようにします。App Engine アプリのレスポンスが遅くならないようにする必要があります。アプリケーションへのウェブ リクエストは、60 秒以内に処理される必要があります(TaskQueue リクエストの場合は 10 分)。このレスポンス時間の制限を超えるプロセスは、ウェブサーバーのオーバーロードを回避するために終了します。

ユーザーがファイルを書き込むことができる場所は /tmp ディレクトリのみです。/tmp 内のファイルは、インスタンスに割り当てられたメモリを消費します。この場所に格納されているファイルは、このインスタンスでのみ使用でき、この特定のインスタンスの存続期間中のみ使用できます。

通常、アプリケーションでリソース ファイルを取得するには、依存しているファイル群をアプリケーションと一緒に WEB-INF の下にパッケージ化し、その後 Class.getResource()ServletContext.getResource() などのメソッドを使用して、アプリケーションからそれらを読み込みます。デフォルトでは、WAR に含まれるすべてのファイルは「リソース ファイル」です。「リソース ファイル」のグループからファイルを除外するには、appengine-web.xml ファイルを使用します。

クラスローダーでの JAR の順序付け

クラス名の衝突を解決するために、JAR ファイルをスキャンしてクラスを検索する順序を定義し直す必要が生じることがあります。このような場合は、appengine-web.xml ファイルに、<priority-specifier> 要素を含む <class-loader-config> 要素を追加して、特定の JAR ファイルが優先的に読み込まれるようにできます。次に例を示します。

<class-loader-config>
  <priority-specifier filename="mailapi.jar"/>
</class-loader-config>

このようにすると、war/WEB-INF/classes/ ディレクトリ内の JAR ファイルではなく「mailapi.jar」が、クラスを検索する最初の JAR ファイルになります。

複数の JAR ファイルが優先されている場合は、元の読み込み順序(互いに対する順序)が使用されます。つまり、<priority-specifier> 要素自体の順序は関係ありません。

スレッド

Java 8 ランタイムでは、App Engine の ThreadManager API と Java の組み込み API(new Thread() など)を使用して、スレッドを作成できます。現在、App Engine API(com.google.appengine.api.*)を呼び出す場合は、リクエスト スレッドまたは ThreadManager API を使用して作成されたスレッドからそれらの API を呼び出す必要があります。

アプリケーションでは次のことが可能です。

currentRequestThreadFactory()ThreadPoolExecutor を作成する場合、サーブレット リクエストが完了する前に shutdown() を明示的に呼び出す必要があります。これを行わないと、リクエストが完了せず、最終的にアプリケーション サーバーで障害が発生します。一部のライブラリで ThreadPoolExecutor が作成される場合があるので注意してください。

アプリケーションは、thread.interrupt() など、現在のスレッドに対するオペレーションを実行できます。

各リクエストは、50 の同時実行 App Engine API リクエスト スレッドに制限されます。

スレッドを使用する場合は、ExecutorRunnable などの高レベル同時実行オブジェクトを使用します。これらのオブジェクトは、割り込みスケジュールと記帳のような、細かいながらも重要な同時実行の詳細の多くを処理します。

App Engine API で作成される同時実行バックグラウンド スレッドの最大数は、インスタンスごとに 10 個です(この制限は App Engine API に関係しない通常の Java スレッドには適用されません)。

ツール

サポートされている IDE

Cloud Tools for Eclipse を導入すると、Eclipse IDE に、App Engine プロジェクト用の新しいプロジェクト ウィザードとデバッグ構成が追加されます。App Engine プロジェクトを Eclipse 内からライブで本番環境にデプロイできます。

Cloud Tools for IntelliJ を使用すると、IntelliJ IDEA 内で App Engine アプリケーションを実行してデバッグできます。IDE を閉じることなく、App Engine プロジェクトをライブで本番環境にデプロイできます。

サポートされているビルドツール

開発プロセスを高速化するには、Apache Maven または Gradle 用の App Engine プラグインを使用できます。

ローカルの開発用サーバー

開発用サーバーを使用すると、アプリケーションの開発とテストのために、ローカルのコンピュータ上でアプリケーションを実行できます。開発用サーバーでは、Cloud Datastore サービスがシミュレートされます。また、開発用サーバーでは、テスト中にアプリケーションが実行するクエリに基づいて、Cloud Datastore インデックスの構成を生成することもできます。

AppCfg

AppCfg は、スタンドアロンの App Engine SDK for Java に含まれています。これは、App Engine で動作しているアプリケーションのコマンドライン操作を処理する多目的ツールです。AppCfg を使用すると、アプリケーションを App Engine にアップロードすることも、Cloud Datastore インデックス構成のみを更新することもできるため、コードを更新する前に新しいインデックスを作成できます。また、アプリのログデータをダウンロードすることもできるため、独自のツールでアプリのパフォーマンスを分析できます。

同時実行とレイテンシ

トラフィックに対処するために必要なインスタンスの数に特に大きく影響するのはアプリケーションのレイテンシです。リクエストを短時間のうちに処理できるサービスであれば、1 つのインスタンスで多くのリクエストを処理できます。

シングルスレッドのインスタンスでは、同時に 1 件のリクエストしか処理できません。そのため、レイテンシと、インスタンスで処理できる 1 秒あたりのリクエスト数の間には直接的な相関関係があります。たとえば、10 ミリ秒のレイテンシでは、1 つのインスタンスで 1 秒間に 100 件のリクエストを処理します。

マルチスレッドのインスタンスでは、多数のリクエストの同時処理が可能です。そのため、CPU 使用量と 1 秒あたりのリクエスト処理数の間に直接の相関関係があります。

Java アプリは、同時リクエストをサポートしているため、1 つのインスタンスで他のリクエストが完了するまで待機している間に、新しいリクエストを処理できます。同時実行性を使用すると、アプリが必要とするインスタンスの数が大幅に少なくなりますが、アプリをマルチスレッド対応として設計する必要があります。

たとえば、B4 インスタンス(約 2.4 GHz)がリクエスト 1 件につき 10 M サイクルを使用する場合、1 つのインスタンスでの 1 秒あたりのリクエスト処理数は 240 件になります。リクエスト 1 件につき 100 M サイクルを使用する場合は、1 つのインスタンスでの 1 秒あたりのリクエスト処理数は 24 件になります。このような数字は理想的な条件を想定したものですが、インスタンスの処理能力という点ではかなり現実的な数字です。

このページは役立ちましたか?評価をお願いいたします。

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

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