Compute Engine での Java Bookshelf の実行

このチュートリアルでは、Google Compute EngineJava Bookshelf アプリを実行する方法を説明します。このチュートリアルに沿って、既存の Java ウェブアプリを Compute Engine にデプロイします。このチュートリアルの手順を進めるにあたり、Bookshelf アプリに精通している必要はありませんが、詳しく知りたい場合は App Engine フレキシブル環境のチュートリアルをご覧ください。

目標

  • 単一の Compute Engine インスタンスに Bookshelf サンプルアプリをデプロイします。
  • マネージド インスタンス グループを使用して、アプリの水平スケーリングを行います。
  • HTTP 負荷分散を使用して、トラフィックを処理します。
  • 自動スケーリングを使用して、トラフィックの変化に対応します。

料金

このチュートリアルでは、以下を含む、Cloud Platform の課金対象となるコンポーネントを使用しています。

  • Google Compute Engine
  • Google Cloud Storage
  • Google Cloud Datastore
  • Google Cloud Logging
  • Google Cloud Pub/Sub

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。 Cloud Platform を初めて使用する方は、無料トライアルをご利用いただける場合があります。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. GCP プロジェクトを選択または作成します。

    [リソースの管理] ページに移動

  3. プロジェクトに対して課金が有効になっていることを確認します。

    課金を有効にする方法について

  4. Cloud Datastore、Cloud Storage、Cloud Pub/Sub API を有効にします。

    APIを有効にする

  5. Cloud SDK をインストールして初期化します。
  6. Java 8Maven をインストールします。

Cloud Storage バケットの作成

Cloud Storage バケットを作成する手順は次のとおりです。バケットは、Cloud Storage でデータを格納する基本的なコンテナです。

バケットを作成するには:

  1. ターミナル ウィンドウで次のコマンドを実行します。

    gsutil mb gs://[YOUR-BUCKET-NAME]

  2. バケットのデフォルト ACL を public-read に設定します。これによりユーザーは、自身がアップロードした画像を見られるようになります。

    gsutil defacl set public-read gs://[YOUR-BUCKET-NAME]

サンプルアプリのクローン作成

サンプル アプリケーションは、GitHub の GoogleCloudPlatform/getting-started-java で入手できます。

  1. レポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/getting-started-java.git
    
  2. サンプル ディレクトリに移動します。

    cd getting-started-java/bookshelf/6-gce
    

アプリの設定

  1. makeBookshelf を編集用に開きます。
  2. 以前に作成したバケットの名前を使用して、BUCKET 変数を設定します。
  3. 必要に応じて、ZONE=us-central1-f を別のゾーンに変更できます。
  4. スクリプトを実行可能にします。chmod +x makeBookshelf
  5. pom.xml を編集用に開きます。
  6. バケットの名前を使用して、bookshelf.bucket プロパティを設定します。
  7. 両方のファイルを保存して閉じます。

    ローカル パソコン上でのアプリの実行

    1. ローカル ウェブサーバーを起動します。

      mvn -Plocal clean jetty:run-exploded -DprojectID=[YOUR-PROJECT-ID]
      

      ここで、[YOUR-PROJECT-ID] は実際のプロジェクト ID です。

    2. ウェブブラウザに次のアドレスを入力します。

      http://localhost:8080

    ローカル ウェブサーバーを停止するには、Ctrl+C キーを押します。

    単一インスタンスにデプロイする

    Single-instance deployment

    このセクションでは、Compute Engine 上でアプリケーションの単一インスタンスを実行する手順について説明します。

    コードをレポジトリに push する

    実行中の Compute Engine インスタンスにコードを配置する方法はいくつかあります。そのうちの 1 つは、Cloud Source Repositories を使用するという方法です。プロジェクトに Git レポジトリを簡単に作成し、アプリケーション コードをアップロードすることができます。その後、起動時にレポジトリから最新バージョンのアプリケーション コードを取得することができます。これにより、アプリケーションの更新時に新しいイメージやインスタンスを設定する必要がないため、非常に便利です。必要な操作は、既存のインスタンスの再起動または新しいインスタンスの作成のみです。

    次のコマンドを入力して Compute Engine のインスタンスを作成し、そのインスタンスにアプリを push します。

    ./makeBookshelf gce
    

    このコマンドは、次のことを行います。

    • プロジェクトをビルドし、Java WAR ファイルを作成します。
    • イメージの保存用に作成しておいた Cloud Storage バケットに WAR ファイルとスクリプトをアップロードします。
    • Compute Engine のインスタンスを作成し、Cloud Logging、Cloud Storage、Cloud Datastore にアクセスできるようにします。
    • Cloud Storage バケットに関するメタデータを渡します。
    • 起動スクリプトを指定します。
    mvn clean package
    
    gsutil cp -r target/${WAR} gce/base gs://${BUCKET}/gce/
    
    gcloud compute firewall-rules create allow-http-bookshelf \
      --allow tcp:80 \
      --source-ranges 0.0.0.0/0 \
      --target-tags ${TAGS} \
      --description "Allow port 80 access to instances tagged with ${TAGS}"
    
    gcloud compute instances create my-app-instance \
      --machine-type=${MACHINE_TYPE} \
      --scopes=${SCOPES} \
      --metadata-from-file startup-script=${STARTUP_SCRIPT} \
      --zone=${ZONE} \
      --tags=${TAGS} \
      --image-family=${IMAGE_FAMILY} \
      --image-project=${IMAGE_PROJECT} \
      --metadata BUCKET=${BUCKET}

    makeBookshelf スクリプトでは、変数を定義します。

    ZONE=us-central1-f
    
    GROUP=frontend-group
    TEMPLATE=$GROUP-tmpl
    MACHINE_TYPE=g1-small
    IMAGE_FAMILY=debian-8
    IMAGE_PROJECT=debian-cloud
    STARTUP_SCRIPT=gce/startup-script.sh
    SCOPES="datastore,userinfo-email,logging-write,storage-full,cloud-platform"
    TAGS=http-server
    
    MIN_INSTANCES=1
    MAX_INSTANCES=10
    TARGET_UTILIZATION=0.6
    
    SERVICE=frontend-web-service
    WAR=bookshelf-1.0-SNAPSHOT.war

    インスタンスでこの起動スクリプトを実行するには約 5 分かかります。次のコマンドを入力すると、インスタンスの進行状況を確認できます。

    gcloud compute instances get-serial-port-output my-app-instance --zone us-central1-f
    

    起動スクリプトが完了したら、/var/logs/daemon.log で新しいインスタンスの起動ログを確認できます。

    インスタンス名は my-app-instance です。次のコマンドを入力すると、インスタンスの外部 IP アドレスを取得できます。

    gcloud compute instances list
    

    アプリの実行を確認するには、ブラウザで次の URL を入力します。

    http://[YOUR_INSTANCE_IP]
    

    インスタンスを削除するには、次のコマンドを入力します。

    ./makeBookshelf down
    

    次のコマンドも同じことを行います。

    gcloud compute instances delete my-app-instance
    

    起動スクリプトを使用してインスタンスを初期化する

    Compute Engine インスタンスからアクセスできる場所にコードを配置したので、次は、コードのダウンロードと実行をインスタンスに指示します。インスタンスが起動または再起動するたびに実行される起動スクリプトをインスタンスに設定することができます。

    ここでは、以下のタスクを実行する起動スクリプトを作成します。

    • Java 8 をインストールし、それをデフォルトにします。

    • Jetty をインストールし、設定します。

    • Java WAR ファイルを Cloud Storage バケットから Jetty の webapps にコピーし、名前を root.war に変更します。このようにしてルート サーブレットにすると、URL で指定する必要がなくなります。

    • Google Cloud Logging エージェントをインストールし、アプリケーション ログをモニタリングするように設定します。これによって、このチュートリアルの前のステップで行ったログ設定がアップロードされ、App Engine フレキシブル環境を使う場合と同じようになります。

    set -e
    set -v
    
    # Talk to the metadata server to get the project id
    PROJECTID=$(curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google")
    BUCKET=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/BUCKET" -H "Metadata-Flavor: Google")
    
    echo "Project ID: ${PROJECTID}  Bucket: ${BUCKET}"
    
    # get our file(s)
    gsutil cp "gs://${BUCKET}/gce/"** .
    
    # Install dependencies from apt
    apt-get update
    apt-get install -t jessie-backports -yq openjdk-8-jdk
    
    # Make Java8 the default
    update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
    
    # Jetty Setup
    mkdir -p /opt/jetty/temp
    mkdir -p /var/log/jetty
    
    # Get Jetty
    curl -L https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.3.8.v20160314/jetty-distribution-9.3.8.v20160314.tar.gz -o jetty9.tgz
    tar xf jetty9.tgz  --strip-components=1 -C /opt/jetty
    
    # Add a Jetty User
    useradd --user-group --shell /bin/false --home-dir /opt/jetty/temp jetty
    
    cd /opt/jetty
    # Add running as "jetty"
    java -jar /opt/jetty/start.jar --add-to-startd=setuid
    cd /
    
    # very important - by renaming the war to root.war, it will run as the root servlet.
    mv bookshelf-1.0-SNAPSHOT.war /opt/jetty/webapps/root.war
    
    # Make sure "jetty" owns everything.
    chown --recursive jetty /opt/jetty
    
    # Configure the default paths for the Jetty service
    cp /opt/jetty/bin/jetty.sh /etc/init.d/jetty
    echo "JETTY_HOME=/opt/jetty" > /etc/default/jetty
    {
      echo "JETTY_BASE=/opt/jetty"
      echo "TMPDIR=/opt/jetty/temp"
      echo "JAVA_OPTIONS=-Djetty.http.port=80"
      echo "JETTY_LOGS=/var/log/jetty"
    } >> /etc/default/jetty
    
    # -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.JavaUtilLog
    
    # Reload daemon to pick up new service
    systemctl daemon-reload
    
    # Install logging monitor. The monitor will automatically pickup logs sent to syslog.
    curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash
    service google-fluentd restart &
    
    service jetty start
    service jetty check
    
    echo "Startup Complete"

    Compute Engine インスタンスの作成と設定

    1. Compute Engine インスタンスを作成します。

      Linux / Mac OS X

      gcloud compute instances create my-app-instance \
          --image-family=debian-8 \
          --image-project=debian-cloud \
          --machine-type=g1-small \
          --scopes userinfo-email,cloud-platform \
          --metadata-from-file startup-script=gce/startup-script.sh \
          --zone us-central1-f \
          --tags http-server
      

      Windows

      gcloud compute instances create my-app-instance ^
          --image-family=debian-8 ^
          --image-project=debian-cloud ^
          --machine-type=g1-small ^
          --scopes userinfo-email,cloud-platform ^
          --metadata-from-file startup-script=gce/startup-script.sh ^
          --zone us-central1-f ^
          --tags http-server
      

      このコマンドは、新しいインスタンスを作成して、Cloud Platform サービスへのアクセスを許可し、起動スクリプトを実行します。インスタンス名は my-app-instance です。

    2. インスタンス作成の進行状況をチェックします。

      gcloud compute instances get-serial-port-output my-app-instance --zone us-central1-f
      

      起動スクリプトが完了すると、コマンド出力の最後のほうに「Finished running startup script」と表示されます。

    3. インスタンスへのトラフィックを許可するファイアウォール ルールを作成します。

      Linux / Mac OS X

      gcloud compute firewall-rules create default-allow-http-8080 \
          --allow tcp:8080 \
          --source-ranges 0.0.0.0/0 \
          --target-tags http-server \
          --description "Allow port 8080 access to http-server"
      

      Windows

      gcloud compute firewall-rules create default-allow-http-8080 ^
          --allow tcp:8080 ^
          --source-ranges 0.0.0.0/0 ^
          --target-tags http-server ^
          --description "Allow port 8080 access to http-server"
      

    4. インスタンスの外部 IP アドレスを取得します。

      gcloud compute instances list
      
    5. 実行中のアプリケーションを確認するために、http://[YOUR_INSTANCE_IP]:8080 に移動します。

      [YOUR_INSTANCE_IP] は、実際のインスタンスの外部 IP アドレスで置き換えてください。

    インスタンスを管理、モニタリングする

    Google Cloud Platform Console を使用して、インスタンスのモニタリングと管理を行うことができます。[コンピューティング] > [Compute Engine] セクションで、実行中のインスタンスを表示し、SSH を使ってそのインスタンスに接続できます。[モニタリング] > [ログ] セクションでは、Compute Engine リソースによって生成されたすべてのログを表示できます。 syslog などの一般的な各種サービスからログを収集するよう、Google Cloud Logging が自動的に構成されます。

    複数のインスタンスを使用して水平スケーリングを行う

    マネージド インスタンスによる複数インスタンスのデプロイ

    Compute Engine では、水平スケーリングを容易に行うことができます。マネージド インスタンス グループと Compute Engine Autoscaler を使用することで、Compute Engine は、必要に応じてアプリケーションの新しいインスタンスを自動的に作成できます。また、需要が少ないときには自動的にインスタンスをシャットダウンできます。HTTP ロードバランサをセットアップすると、マネージド インスタンス グループ内の各インスタンスにトラフィックを分散できます。

    マネージド インスタンス グループを作成する

    マネージド インスタンス グループは、同じインスタンス テンプレートに基づく同種のインスタンスのグループです。インスタンス テンプレートは、ソースイメージやディスクサイズ、スコープ、メタデータ(例: 起動スクリプト)など、インスタンスの構成を定義します。

    1. まず、テンプレートを作成します。

      ./makeBookshelf gce-many
      

    2. 次に、インスタンス グループを作成します。

      gcloud compute instance-groups managed \
        create ${GROUP} \
        --base-instance-name ${GROUP} \
        --size ${MIN_INSTANCES} \
        --template ${TEMPLATE} \
        --zone ${ZONE}

      --size パラメータは、グループ内のインスタンス数を指定します。すべてのインスタンスが起動スクリプトの実行を完了すると、各インスタンスの外部 IP アドレスとポート 8080 を使用することで、各インスタンスに個別にアクセスできます。インスタンスの外部 IP アドレスを調べるには、「gcloud compute instances list」と入力します。マネージド インスタンスには、同じプレフィックス my-app で始まる名前が付きます。これは --base-instance-name パラメータで指定したものです。

    ロードバランサを作成する

    テストやデバッグであれば単独のインスタンスでも十分ですが、ウェブ トラフィックを処理するのであれば、ロードバランサを使用して、利用できる複数のインスタンスの間で自動的にトラフィックを分配することをおすすめします。ロードバランサを作成する手順は次のとおりです。

    1. ヘルスチェックを作成します。ロードバランサはヘルスチェックを使用して、トラフィックを処理できるインスタンスを判断します。

      gcloud compute http-health-checks create ah-health-check \
        --request-path /_ah/health \
        --port 80

    2. 名前付きポートを作成します。HTTP ロードバランサは、http サービスを検索して、トラフィックの送信先となるポートを判別します。既存のインスタンス グループで、ポート 8080 に「http」という名前を付けます。

    3. バックエンド サービスを作成します。バックエンド サービスは、負荷分散されたトラフィックのターゲットとして機能します。バックエンド サービスにより、トラフィックの送信先となるインスタンス グループおよび使用するヘルスチェックが定義されます。

      gcloud compute backend-services create $SERVICE \
        --http-health-checks ah-health-check

    4. バックエンド サービスを追加します。

      gcloud compute backend-services add-backend $SERVICE \
        --instance-group $GROUP \
        --zone $ZONE

    5. URL マップとプロキシを作成します。

      URL マップは、どの URL がどのバックエンド サービスにつながるのかを定義します。今回のサンプルでは、1 つのバックエンド サービスですべてのトラフィックを処理しています。複数のリージョンやグループ間でリクエストを負荷分散する場合は、複数のバックエンド サービスを作成します。プロキシは、トラフィックを受信し、URL マップを使用してバックエンド サービスにトラフィックを転送します。

      1. URL マップを作成します。

        gcloud compute url-maps create $SERVICE-map \
          --default-service $SERVICE

      2. プロキシを作成します。

        gcloud compute target-http-proxies create $SERVICE-proxy \
          --url-map $SERVICE-map

    6. グローバル転送ルールを作成します。グローバル転送ルールにより、公開 IP アドレスとポートがプロキシに関連付けられます。

      gcloud compute forwarding-rules create $SERVICE-http-rule \
        --global \
        --target-http-proxy $SERVICE-proxy \
        --port-range 80

    オートスケーラーを設定する

    ロードバランサにより、すべての正常なインスタンス間でトラフィックが分散されるようになりました。しかし、すべてのインスタンスを合わせても処理できないほどのトラフィックが生じた場合にはどうなるでしょうか。インスタンスを手動で追加することもできます。しかし、もっと良い方法として Compute Engine Autoscaler があります。Compute Engine Autoscaler を構成すると、トラフィックの需要に応じてインスタンスの作成と削除を自動的に行うことができます。

    1. オートスケーラーを作成します。

      gcloud compute instance-groups managed set-autoscaling \
        $GROUP \
        --max-num-replicas $MAX_INSTANCES \
        --target-load-balancing-utilization $TARGET_UTILIZATION \
        --zone $ZONE

      上記のコマンドにより、マネージド インスタンス グループにオートスケーラーが作成され、最大 10 個のインスタンスまで自動的にスケーリングされます。ロードバランサの使用率が 50% を超えると新しいインスタンスが追加され、使用率が 50% を下回るとインスタンスが削除されます。

    2. ファイアウォール ルールを作成します(まだ作成していない場合)。

      Linux / Mac OS X

      gcloud compute firewall-rules create default-allow-http-8080 \
          --allow tcp:8080 \
          --source-ranges 0.0.0.0/0 \
          --target-tags http-server \
          --description "Allow port 8080 access to http-server"
      

      Windows

      gcloud compute firewall-rules create default-allow-http-8080 ^
          --allow tcp:8080 ^
          --source-ranges 0.0.0.0/0 ^
          --target-tags http-server ^
          --description "Allow port 8080 access to http-server"
      

    3. 進行状況をチェックします。

      gcloud compute backend-services get-health my-app-service
      

      少なくとも 1 つのインスタンスが HEALTHY をレポートするまで、チェックを繰り返します。

    アプリケーションを表示する

    1. ロードバランサの転送 IP アドレスを取得します。

      gcloud compute forwarding-rules list --global
      

      転送ルールの IP アドレスは IP_ADDRESS 列に表示されます。

    2. リストから取得した IP アドレスをブラウザに入力します。負荷分散型の自動スケーリング アプリが Google Compute Engine 上で動作していることを確認します。

    デプロイを管理、モニタリングする

    複数インスタンスの管理は、単一インスタンスの管理と同様に簡単です。負荷分散、自動スケーリング、マネージド インスタンス グループをモニタリングするには、GCP Console を使用します。

    インスタンス グループと自動スケーリングの構成を管理するには、[コンピューティング] > [Compute Engine] > [インスタンス グループ] を使用します。

    URL マップやバックエンド サービスなど、負荷分散の構成を管理するには、[コンピューティング] > [Compute Engine] > [HTTP 負荷分散] セクションを使用します。

    デプロイ スクリプト

    サンプル アプリケーションには、Compute Engine へのデプロイ方法を示すスクリプトが含まれています。deploy.sh という名前のこのスクリプトは、自動スケーリングと負荷分散を行う完全なアプリケーション デプロイを実行します。詳細については、複数のインスタンスを使用して水平スケーリングを行う方法をご覧ください。

クリーンアップ

このチュートリアルで使用するリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

削除スクリプトを実行する

deploy.sh スクリプトをすでに実行した場合、teardown.sh スクリプトを実行すると、deploy.sh スクリプトによって作成されたリソースをすべて削除できます。これにより、プロジェクトが deploy.sh スクリプトの実行前の状態に戻るので、以降の課金を回避できます。チュートリアルの開始時に作成した単一インスタンスとストレージ バケットを削除するには、次のセクションの手順に従ってください。

手動でリソースを削除する

このチュートリアルの手順を手動で進めてきた場合、Compute Engine インスタンスと Cloud Storage バケットを手動で削除できます。

Compute Engine インスタンスを削除する

Compute Engine インスタンスを削除する手順は次のとおりです。

  1. GCP Console の [VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. 削除するインスタンスの隣のチェックボックスをオンにします。
  3. ページの上部にある、[削除] ボタンをクリックし、インスタンスを削除します。

Cloud Storage バケットを削除する

Cloud Storage バケットを削除する手順は次のとおりです。

  1. GCP Console で、Cloud Storage ブラウザに移動します。

    Cloud Storage ブラウザに移動

  2. 削除したいバケットの隣にあるチェックボックスをクリックします。
  3. ページの上部にある [削除] ボタンをクリックし、バケットを削除します。

次のステップ

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