Go 1.9 ランタイム環境

App Engine では、Go プログラミング言語を使用してウェブ アプリケーションを作成できます。作成した Go アプリケーションは、Google のスケーラブルなインフラストラクチャ上で動作し、大規模な永続ストレージとサービスを利用します。

はじめに

App Engine は、安全なサンドボックス環境を使用して Go アプリケーション コードをビルドし、実行します。アプリは、この環境と通信することで、ウェブ リクエストの受信、作業の実行、レスポンスの送信を行います。

App Engine SDK for Go は、標準の Go http パッケージと似たインターフェースを備えています。したがって、App Engine の Go アプリの作成方法は、スタンドアロンの Go ウェブサーバーの作成方法と似ています。

Go ランタイム環境では Go バージョン 1.9 が使用されます。App Engine SDK には Go コンパイラと標準ライブラリが組み込まれているため、他に必要なものはありません。他のランタイムと同様に、標準ライブラリの機能のすべてがサンドボックス内で使用できるわけではありません。たとえば、ソケットを開いたりファイルに書き込んだりすると、os.ErrPermission エラーが返されます。

App Engine SDK には、アプリをコンパイルするための自動ビルドサービスが付属しているため、コンパイラを自分で呼び出す必要がありません。また、Python SDK と同様に、作成したアプリはソースが変更されるたびに自動的に再ビルドされます。

App Engine の Go ランタイム環境は、goroutine を完全にサポートしていますが、並列実行はサポートしていません。goroutine は単一のオペレーティング システム スレッドにスケジュールされます。このシングルスレッド制限は、今後のバージョンで解除される予定です。特定のインスタンスで複数のリクエストを同時に処理することができます。これは、1 つのリクエストで Cloud Datastore API の呼び出しを待っている間に、同じインスタンスで別のリクエストを処理できることを意味します。

Go アプリケーションは、使用できるライブラリに制限がある安全なサンドボックス環境内で動作します。たとえば、ローカル ファイル システムにデータを書き込んだり、任意のネットワークに接続したりすることはできません。代わりに、App Engine が提供するスケーラブルなサービスを利用して、データの保存やインターネット経由の通信を行います。

App Engine プラットフォームには、コードから呼び出せる多数のサービスが用意されています。

Go を使用したアプリの構築に、Go と App Engine を使用してウェブ アプリケーションを開発する手順が記載されています。

Go ランタイムの選択

app.yaml 構成ファイルで Go ランタイム環境を指定します。アプリケーションを App Engine にデプロイするときに、このファイルが使用されます。次に例を示します。

runtime: go
api_version: go1

1 つ目の要素 runtime で、Go ランタイム環境を選択します。

2 番目の要素 api_version で、使用する Go ランタイム環境のバージョンを選択します。この記事の執筆時点で、Go 環境の最新バージョンは go1 であり、Go の最新リリース(現時点で go1.9)のエイリアスです。App Engine チームが既存のコードと互換性のない変更を環境にリリースした場合は、バージョン ID がインクリメントされます。つまり、アプリを更新して api_version 設定を変更できるようになるまで、古い API の使用を継続できます。使用可能な api_version 値は go1go1.9 です。

Go アプリの編成

Go で App Engine アプリを開発すると、コードは 1 つ以上のサービスに分割されます。各サービスは、通常、そのサービス専用の app.yaml ファイルとともに、個別のディレクトリに格納されます。

- project-dir
   - service1-dir
      app.yaml
      src1-1.go
      src1-2.go
   - service2-dir
      app.yaml
      src2-1.go
      src2-2.go

Go アプリケーションは、ソースファイルのディレクトリ構造を反映するパッケージに編成されています。App Engine のソースコードで import ステートメントを使用した場合、import 内の相対パスは次の 2 つのことを意味すると捉えられます。

  • サービスの app.yaml ファイルの格納先ディレクトリに相対している

  • GOPATH 内のすべてのディレクトリの src サブディレクトリに相対している(これを「完全修飾」インポートパスといいます)

たとえば、GOPATH が次のように定義されているとします。

export GOPATH=/home/fred/go

上のプロジェクト ディレクトリ例の src1-1.go ファイルには次のステートメントが含まれています。

import "foo/bar"

App Engine SDK は、service1 が実行またはデプロイされると、次の場所にあるパッケージ「foo/bar」を探します。

project-dir/service1/foo/bar
/home/fred/go/src/foo/bar

GOPATH にパッケージ ソースを含める場合は、app.yaml ファイルを含む App Engine プロジェクト内のディレクトリ以下にソースコードを配置しないように注意する必要があります。この位置に配置すると、パッケージが 2 回読み込まれる可能性があります。サービスのディレクトリの相対パスに対して 1 回、完全修飾パスに対してもう 1 回です。これは修正が困難な問題の原因になり得るため、プロジェクトと GOPATH のスキャンでこのケースが検出された場合、エラーとして報告されます。

最良の結果を得るために、以下の操作をおすすめします。

  • 各サービス用にプロジェクトで別々のディレクトリを作成します。
  • 各サービスのディレクトリには、サービスの app.yaml ファイルと 1 つ以上の .go ファイルを含めます。
  • サービス ディレクトリにはサブディレクトリを作成しないでください。
  • .go ファイルでのパッケージのインポートでは、完全修飾パスが必要とされるため、すべてのパッケージ コードをプロジェクト ディレクトリの直下の src ディレクトリの下に配置します(プロジェクト ディレクトリの下には配置しないでください)。

サービスの構造化の詳細については、App Engine の概要をご覧ください。

Go の GOPATH の概要と App Engine 開発との関係については、App Engine SDK とワークスペースをご覧ください。

サンドボックス

App Engine が複数のアプリケーションへのリクエストを複数のウェブサーバーに分散できるようにし、かつアプリケーションが相互に干渉しないようにするために、アプリケーションは制限された「サンドボックス」環境で実行されます。この環境でアプリケーションは、コードの実行、Cloud Datastore 内でのデータの保存とクエリ、App Engine メール、URL 取得、ユーザー サービスの使用、ユーザーのウェブ リクエストの確認とレスポンスの準備が可能となります。

App Engine アプリケーションでは、次のことはできません。

  • ファイルシステムへの書き込み。アプリケーションは、データを永続的に保存するために、Cloud Datastore を使用する必要があります。ファイルシステムからの読み取りは可能です。また、アプリケーションでアップロードされたアプリケーション ファイルはすべて利用可能です。

  • 遅いレスポンス。アプリケーションへのウェブ リクエストは、数秒以内に処理される必要があります。レスポンスまでに非常時に長い時間がかかるプロセスは、ウェブサーバーの過負荷を防ぐために終了します。

  • その他の種類のシステムコールの実行。

Go ランタイムは、サンドボックス ポリシーに違反する標準ライブラリ パッケージの使用を制限します。そうした関数は、os.ErrPermission エラーを返すスタブに置き換えられるか、または完全に削除されました。

バックグラウンド リクエスト

手動または基本のスケーリング インスタンス上で動作するコードは、生成元のリクエストよりも長く存続できるリクエストを開始できます。そのため、インスタンスは、任意の周期的タスクまたはスケジュールされたタスクを実行したり、ユーザーにリクエストが返された後もバックグラウンドで作業を継続したりできます。

runtime.RunInBackground を使用して、バックグラウンド goroutine 内のコードを実行します。

err := runtime.RunInBackground(c, func(c appengine.Context) {
  // do something...
})

指定された関数は、指定されたコンテキストとは異なる(かつ長く存続する可能性がある)バックグラウンド コンテキストで呼び出されます。インスタンスあたりの同時バックグラウンド リクエスト数は 10 個に制限されていることに注意してください。

ツール

SDK for App Engine には、アプリケーションのテストとアプリケーション ファイルのアップロードのためのツールが含まれています。

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

gcloud ツールは、App Engine で実行されているアプリケーションに対するすべてのコマンドライン操作を処理します。gcloud app deploy を使用すると、アプリケーションを App Engine にアップロードしたり、Cloud Datastore インデックス構成などの個別の構成ファイルを更新したりできます。これにより、コードをデプロイする前に新しいインデックスを作成できます。また、アプリのログデータを表示して、独自のツールでアプリのパフォーマンスを分析することもできます。

同時実行とレイテンシ

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

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

Go ランタイム インスタンスは複数のリクエストを同時に処理できますが、CPU 時間を占有するのは実行中の 1 つの goroutine だけです。その間、他の goroutine は I/O(ファイルの読み込み、システムまたは API の呼び出し)を実行できます。

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

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

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