Google Compute Engine と gRPC を使用したモバイルアプリの作成

gRPC フレームワークにより、モバイルアプリはバックエンド サービスのメソッドをローカル オブジェクトと同様に呼び出すことができます。モバイルアプリは、gRPC の使用により通信帯域をより効率的に使用することができ、Google Cloud Platform で動作するバックエンド サービスとアプリ間の通信で発生するレイテンシが削減できます。

Google Compute Engine でモバイル バックエンドを実行し、モバイルアプリとバックエンド サーバー間の通信プロトコルに gRPC を使用すると、以下のような利点があります。

  • オンプレミスまたは仮想マシン上で実行されている既存のサービスを Cloud Platform に移行する最速の方法です。
  • HTTP/S よりも通信帯域をより効率的に使用できます。
  • 仮想マシンとサーバーの構成がすべて管理できます。
  • サードパーティ ライブラリが使用できます。
  • オートスケーラーを構成して、仮想マシンの数を必要な規模にスケーリングできます。

Compute Engine でサービスを実行する場合は、サーバーのメンテナンスと更新を手動で行う必要があります。モバイル バックエンド サービスを作成する他の方法については、Google Cloud Platform を使用したモバイルアプリの作成をご覧ください。

このチュートリアルでは、例として Stickynotes というモバイルアプリを作成する作業を一通り行います。このアプリでは、Compute Engine で動作するバックエンド サービスとの接続に gRPC を使用します。

Stickynotes には、フロントエンド モバイルアプリとバックエンド サービスのコードが含まれています。モバイルアプリでは、テキスト フィールドにメッセージが入力できます。アプリは gRPC を使用してバックエンド サービスにそのメッセージを送信します。バックエンド サービスは draw2d を使用してテキスト メッセージを画像に変換し、モバイルアプリに返します。その後、モバイルアプリが黄色の背景上にそのメッセージの画像を表示します。

クライアント アプリは iOS アプリであり、バックエンド サービスは Go で記述されています。

目標

このチュートリアルの学習内容は次のとおりです。

  • バックエンド サービスとの接続に gRPC を使用する iOS モバイルアプリを作成する。
  • Compute Engine 上で gRPC バックエンド サービスを構成し実行する。

費用

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

  • Google Compute Engine

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

始める前に

  1. GCP Console で [リソースの管理] ページに移動します。

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

  2. 既存のプロジェクトを選択するか、[プロジェクトを作成] をクリックして、新しい GCP プロジェクトを作成します。

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

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

以上の手順を完了したら、次のソフトウェアをインストールします。

  • Git
  • XCode 7.2 以降
  • Go

    Go が PATH 変数で指定されたパスにインストールされていることを確認してください。通常は /usr/local/go/bin です。

    オーナーとしてのユーザー アカウントを使用して Go をインストールします。root としてインストールする場合は、Go がインストールされているディレクトリで次のコマンドを実行して所有権を変更し、<username> を自分のユーザー名に置き換えます。

    sudo chown -R <username> go
    
  • Cocoapods

    sudo gem install cocoapods
    
  • Homebrew

    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    
  • gRPC プラグインを含む protoc

    curl -fsSL https://goo.gl/getgrpc | bash -
    

サンプルコードのクローンを作成する

git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git

次に、/solutions/stickynoteapi/gRPC に移動して、このソリューションのサンプルコードを見つけます。

サーバーをローカルで実行する

/stickynoteapi/gRPC/Go ディレクトリで、次のコマンドを実行します。

sh SETUP

次の出力が表示されます。

0. Ensure that protoc is installed.
/usr/local/bin/protoc
OK
1. Set gopath and search path
2. Get the Go plugin for protoc
3. Run protoc to generate the service API code
4. Get the server and client dependencies
5. Build the server and client
6. Stop any previously-running instances of the server
No matching processes belonging to you were found
7. Start the server
8. Run the client
2016/03/03 15:53:21 OK: message.png
9. Open the image in message.png

このセットアップでローカル クライアントも実行され、「Remember the milk.」というフレーズを使用してサーバーがテストされ、そのメッセージを含む画像が生成されます。

Remember the milk.

コマンドライン クライアントを使用して独自のメッセージに基づく画像を生成するには、次のコマンドを実行します。

./client "This is a test..."

ファイル /solutions/stickynoteapi/gRPC/Go/go/src/server/server.go には、gRPC サーバーを実行するコードが含まれています。このコードは、2 つの要素(1 つはリクエストを表し、もう 1 つはレスポンスを表します)を含む構造体 StickyNoteServer も定義します。

type StickyNoteServer struct{}

var stickyNoteServer StickyNoteServer

main 関数によって、ルートレベル ディレクトリの gRPC サーバーが定義され、ポート 8080 でトラフィックがリッスンされます。サーバーでは IP アドレスやドメインは指定されないため、変更せずにこのコードを Compute Engine で実行できます。

func main() {
	var err error
	var lis net.Listener
	var grpcServer *grpc.Server
	if !useSSL {
		lis, err = net.Listen("tcp", ":8080")
		if err != nil {
			log.Fatalf("failed to listen: %v", err)
		}
		grpcServer = grpc.NewServer()
	} else {
		certFile := "ssl.crt"
		keyFile := "ssl.key"
		creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
		lis, err = net.Listen("tcp", ":443")
		if err != nil {
			log.Fatalf("failed to listen: %v", err)
		}
		grpcServer = grpc.NewServer(grpc.Creds(creds))
	}
	pb.RegisterStickyNoteServer(grpcServer, &stickyNoteServer)
	grpcServer.Serve(lis)
}

Get 関数は gRPC リクエストでメッセージを受け取り、sticky.go に定義された関数を使用して、そのメッセージに基づいて画像を作成し、gRPC レスポンスで画像を返します。

func (s *StickyNoteServer) Get(ctx context.Context, r *pb.StickyNoteRequest) (*pb.StickyNoteResponse, error) {
	var sticky Sticky
	sticky.Message = r.Message
	sticky.Centered = false

	resp := &pb.StickyNoteResponse{}
	stickyBytes, err := sticky.DrawPNG(512, 512)
	resp.Image = *stickyBytes

	return resp, err
}

ローカル サーバーは実行中のままにし、それを使用してクライアント アプリケーションをテストできるようにします。

ローカル サーバーでの iOS クライアントの実行

  1. /stickynoteapi/gRPC/Objective-C ディレクトリで次のコマンドを実行し、BoringSSL、Protobuf、gRPC の依存関係をインストールします。インストールには数分かかります。

    pod install
    

    次の出力が表示されます。

    Analyzing dependencies
    Fetching podspec for `stickynote` from `stickyapi`
    Downloading dependencies
    Installing BoringSSL (2.0)
    Installing Protobuf (3.0.0-beta-2)
    Installing gRPC (0.12.0)
    Installing stickynote (0.0.1)
    Generating Pods project
    Integrating client project
    
    [!] Please close any current Xcode sessions and use
    `stickynotes.xcworkspace` for this project from now on.
    Sending stats
    Pod installation complete! There is 1 dependency from the Podfile and 4
    total pods installed.
    
  2. Xcode で Cocoapods により作成されたワークスペース stickynotes.xcworkspace を開きます。

  3. [Product] > [Scheme] > [stickynotes] をクリックして、現在のスキームを選択します。

  4. [Product] > [Run] を選択し、クライアント アプリケーションをビルドして起動します。Protobuf と gRPC で発生する警告は無視します。

  5. テキスト フィールドにメッセージを入力し、[return] をタップします。

メッセージが表示された黄色の付箋の画像が、テキスト フィールドの下に表示されます。

これはテストです...

クライアント アプリによって、バックエンド サービスの場所がファイル StickyNotesViewController.m に設定されます。テスト用に、これはローカルホストに初期設定されています。

static NSString * const kHostAddress = @"localhost";

テキスト フィールドにメッセージを入力した後、[return] をタップすると、次のアクションが開始されます。メッセージがクエリ文字列にエンコードされます。その後、開いているストリーミング接続にそのクエリが送信されます。

- (IBAction)textDidChange:(UITextField *) sender {
  if ([_streamSwitch isOn]) {
    StickyNoteRequest *request = [StickyNoteRequest message];
    request.message = sender.text;
    [_writer writeValue:request];
  }
}

openStreamingConnection 関数によりストリーミング接続が開きます。

- (void) openStreamingConnection {
  _writer = [[GRXBufferedPipe alloc] init];
  _updateCall = [_client RPCToUpdateWithRequestsWriter:_writer
                                          eventHandler:^(BOOL done, StickyNoteResponse *response, NSError *error) {
                                            [self handleStickynoteResponse:response andError:error];
                                          }];
  [_updateCall start];
}

Compute Engine でのサーバーの実行

  1. Google Cloud Platform Console の [インスタンスの作成] ページに移動します。

    [インスタンスの作成] ページに移動

    1. [名前] を sticky-grpc に設定します。
    2. [作成] を選択します。

    インスタンスの作成

  2. GCP Console で [ファイアウォール ルールの作成] ページに移動します。

    [ファイアウォール ルールの作成] ページに移動

    1. [名前] に「default-allow-grpc」と入力します。
    2. [ソースフィルタ] で、[すべてのソースから許可(0.0.0.0./0)] を選択します。
    3. [許可対象プロトコル / ポート] に「tcp:8080」と入力します。
    4. [作成] を選択します。

    SSH の選択

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

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

    1. sticky-grpc の横に表示された外部 IP アドレスを書き留めます。
    2. [SSH] を選択します。

    SSH の選択

  4. インスタンスに Git をインストールします。

    sudo apt-get update
    sudo apt-get install git
    
  5. Stickynotes サーバーコードのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git
    
  6. Go と protoc をインストールします。/solutions/stickynoteapi/gRPC/Go/ ディレクトリで次のコマンドを実行します。

    sh INSTALL
    
  7. INSTALL スクリプトにより設定された新しい環境変数を読み込みます。

    source $HOME/.bash_profile
    
  8. インスタンスで Stickynotes サーバーを開始します。/solutions/stickynoteapi/gRPC/Go/ ディレクトリで次のコマンドを実行します。

    sh SETUP
    
  9. Xcode で、StickyNotesViewController.m を編集し、ローカルホストを変更して、ステップ 2 で書き留めた Compute Engine インスタンスの外部 IP アドレスを指定します。

    // static NSString \* const kHostAddress = @"localhost";
    static NSString \* const kHostAddress = @"198.51.100.0";
    
  10. [File] > [Save] を選択して、変更内容を保存します。

  11. [Product] > [Scheme] > [stickynotes] をクリックして、現在のスキームを選択します。

  12. [Product] > [Run] を選択し、クライアント アプリケーションをビルドして起動します。

  13. テキスト フィールドにメッセージを入力し、[return] をタップします。

グレーの背景が置き換えられ、メッセージが表示された黄色の付箋の画像が表示されます。

リモート サーバーでテスト中...

クリーンアップ

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

プロジェクトの削除

課金を停止する最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除する手順は次のとおりです。

  1. GCP Console で [プロジェクト] ページに移動します。

    プロジェクト ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

インスタンスの削除

Compute Engine インスタンスを削除するには:

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

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

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

デフォルトのネットワークのファイアウォール ルールの削除

ファイアウォール ルールを削除するには:

  1. GCP Console で、[ファイアウォール ルール] ページに移動します。

    [ファイアウォール ルール] ページに移動

  2. 削除するファイアウォール ルールの横にあるチェックボックスをクリックします。
  3. ページの上部にある、[削除] ボタンをクリックし、ファイアウォール ルールを削除します。

次のステップ

このサンプルは、gRPC を介して、Compute Engine で実行されるコードにモバイルアプリを接続する基本的な方法を示しています。このサンプルの機能を拡張して実際のアプリに使用する場合は、次の拡張を追加することを検討してください。

  • 静的 IP アドレスをサーバーに追加する -- デフォルトで、Compute Engine インスタンスに関連付けられた外部アドレスは一時的なものです。本番環境のアプリの場合、静的 IP アドレスをインスタンスに追加する必要があります。詳細については、インスタンスの IP アドレスの構成をご覧ください。

  • 負荷分散とオートスケーリングを追加する -- ロードバランサとオートスケーラ-を設定して、要求が増加したときに超過インスタンスをすばやく処理し、インスタンス間で均等にトラフィックをルーティングすることで、トラフィックの急上昇を適切に処理します。詳細については、HTTP(S) 負荷分散の設定インスタンスのグループの自動スケーリングをご覧ください。

  • バックエンド サービスに他のホスティング オプションを検討する -- Compute Engine では、仮想マシンの制御を最大限に行うことができますが、その代わりに、インスタンスを手動で更新および管理する必要があります。Cloud Platform でモバイル バックエンド サービスをホストするその他の方法については、Google Cloud Platform を使用したモバイルアプリの作成をご覧ください。

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

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