App Engine から Cloud SQL への接続

このページには、App Engine で実行されているサービスから Cloud SQL インスタンスに接続するための情報と例が含まれています。

Cloud SQL は、クラウド上の PostgreSQL と MySQL のリレーショナル データベースを簡単に設定、維持、運用、管理できるようにするフルマネージド データベース サービスです。

App Engine は、大規模なウェブ アプリケーションを開発およびホスティングするための、フルマネージド型のサーバーレス プラットフォームです。アプリの開発では複数の一般的な言語、ライブラリ、フレームワークからの選択が可能で、開発したアプリのインスタンスのサーバー プロビジョニングとスケーリングは App Engine によってオンデマンドで行われます。

Cloud SQL インスタンスの設定

  1. Cloud SQL for MySQL インスタンスを作成します

  2. [インスタンスの詳細] ページで、インスタンスの INSTANCE_CONNECTION_NAME を見つけます。これは、PROJECT_ID:REGION:INSTANCE_ID の形式で、接続先の Cloud SQL インスタンスを識別するために使用されます。

  3. まだ Cloud SQL Admin API を有効にしていない場合は有効にします。

    API を有効にする

App Engine の構成

スタンダード

App Engine では、使用するサービス アカウントに正しいアクセス許可が設定されていること以外に、特別な構成は必要ありません。

フレキシブル

最適に機能するオプションを使用して、プロジェクトの app.yaml ファイルを更新します。インスタンスのカンマ区切りのリストを使用すると、複数のオプションを一度に指定できます。

UNIX ドメイン ソケットの有効化

UNIX ドメイン ソケットを有効にするには、1 つのインスタンスに接続するのか、複数のインスタンスに接続するのかに応じて、次のいずれかをプロジェクトの app.yaml ファイルに追加します。

beta_settings:
      cloud_sql_instances: <INSTANCE_CONNECTION_NAME>
    
beta_settings:
      cloud_sql_instances: <INSTANCE_CONNECTION_NAME>,<INSTANCE_CONNECTION_NAME_2>,...
    

TCP ポートの有効化

ローカル TCP ポートを有効にするには、1 つのインスタンスに接続するのか、複数のインスタンスに接続するのかに応じて、次のいずれかをプロジェクトの app.yaml ファイルに追加します。

beta_settings:
      cloud_sql_instances: <INSTANCE_CONNECTION_NAME>=tcp:<PORT>
    
beta_settings:
      cloud_sql_instances: <INSTANCE_CONNECTION_NAME>=tcp:<PORT>,<INSTANCE_CONNECTION_NAME_2>=tcp:<PORT>,...
    

App Engine はサービス アカウントを使用して Cloud SQL への接続を承認します。正常に接続するためには、このサービス アカウントに適切な IAM 権限が必要です。特に構成しない限り、デフォルトのサービス アカウントの形式は service-PROJECT_NUMBER@gae-api-prod.google.com.iam.gserviceaccount.com になります。

必要に応じて、他のアプリケーションやクライアントに Cloud SQL インスタンスへの接続を許可、または禁止できます。詳細については、認証のオプションを参照して、インスタンスへの接続を許可するユーザーと場所を設定してください。

2 つの異なるプロジェクトでリソースを接続する場合は、両方のプロジェクトで、正しい IAM ロールを有効にし、サービス アカウントに正しい権限を付与していることを確認します。

サービスのサービス アカウントが次のいずれかの IAM ロールを持つことを確認します。

  • Cloud SQL Client(推奨)
  • Cloud SQL Editor
  • Cloud SQL Admin

または、次の IAM 権限を手動で割り当てることもできます。

  • cloudsql.instances.connect
  • cloudsql.instances.get

サービス アカウントに IAM ロールを追加する方法の詳細については、サービス アカウントへのロールの付与をご覧ください。

Cloud SQL への接続

正しく構成されたら、形式 /cloudsql/INSTANCE_CONNECTION_NAME を使用して、Cloud SQL インスタンスの UNIX ドメイン ソケットにサービスを接続できます。

これらの接続は、追加構成なしで自動的に暗号化されます。

以下に示すコードサンプルは、GitHub サイトに掲載されているより詳細な例からの抜粋です。詳しく見るには、View on GitHub をクリックしてください。GitHub サイトで、コードと同じディレクトリにある README ファイルを探します。README ファイルには、認証情報、接続パス、データベース変数のための環境変数の使用など、重要な設定トピックが記載されています。README ファイルには、テストとデプロイのヒントも記載されています。

App Engine フレキシブル環境は、TCP 経由の接続もサポートしています。TCP ポートを使用してインスタンスを構成した場合、代わりに 172.17.0.1:PORT に接続するようにアプリケーションを構成します。

Python

# The SQLAlchemy engine will help manage interactions, including automatically
    # managing a pool of connections to your database
    db = sqlalchemy.create_engine(
        # Equivalent URL:
        # mysql+pymysql://<db_user>:<db_pass>@/<db_name>?unix_socket=/cloudsql/<cloud_sql_instance_name>
        sqlalchemy.engine.url.URL(
            drivername="mysql+pymysql",
            username=db_user,
            password=db_pass,
            database=db_name,
            query={"unix_socket": "/cloudsql/{}".format(cloud_sql_connection_name)},
        ),
        # ... Specify additional properties here.
        # ...
    )
このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub にあるソースコードを表示してください。

Java

// The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // Configure which instance and what database user to connect with.
    config.setJdbcUrl(String.format("jdbc:mysql:///%s", DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "postgres"
    config.setPassword(DB_PASS); // e.g. "my-password"

    // For Java users, the Cloud SQL JDBC Socket Factory can provide authenticated connections.
    // See https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory for details.
    config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
    config.addDataSourceProperty("cloudSqlInstance", CLOUD_SQL_CONNECTION_NAME);
    config.addDataSourceProperty("useSSL", "false");

    // ... Specify additional connection properties here.
    // ...

    // Initialize the connection pool using the configuration object.
    DataSource pool = new HikariDataSource(config);
このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub にあるソースコードを表示してください。

Node.js

let pool;
    const createPool = async () => {
      pool = await mysql.createPool({
        user: process.env.DB_USER, // e.g. 'my-db-user'
        password: process.env.DB_PASS, // e.g. 'my-db-password'
        database: process.env.DB_NAME, // e.g. 'my-database'
        // If connecting via unix domain socket, specify the path
        socketPath: `/cloudsql/${process.env.CLOUD_SQL_CONNECTION_NAME}`,
        // If connecting via TCP, enter the IP and port instead
        // host: 'localhost',
        // port: 3306,

        //...
      });
    };
    createPool();
このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub にあるソースコードを表示してください。

C#

var connectionString = new MySqlConnectionStringBuilder(
        Configuration["CloudSql:ConnectionString"])
    // ConnectionString set in appsetings.json formatted as:
    // "Uid=aspnetuser;Pwd=;Host=cloudsql;Database=votes"
    {
        // Connecting to a local proxy that does not support ssl.
        SslMode = MySqlSslMode.None,
    };
    connectionString.Pooling = true;
    // ...
    DbConnection connection =
        new MySqlConnection(connectionString.ConnectionString);
このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub にあるソースコードを表示してください。

Ruby

development:
      adapter: mysql2
      # ...
      username: <%= ENV["MYSQL_USERNAME"] %>
      password: <%= ENV["MYSQL_PASSWORD"] %>
      database: <%= ENV.fetch("MYSQL_DATABASE") { "vote_development" } %>
      socket:   "/cloudsql/<%= ENV["INSTANCE_CONNECTION_NAME"] %>"
このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub にあるソースコードを表示してください。

Go

var (
    	dbUser                 = mustGetenv("DB_USER")
    	dbPwd                  = mustGetenv("DB_PASS")
    	instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME")
    	dbName                 = mustGetenv("DB_NAME")
    )

    var dbURI string
    dbURI = fmt.Sprintf("%s:%s@unix(/cloudsql/%s)/%s", dbUser, dbPwd, instanceConnectionName, dbName)

    // dbPool is the pool of database connections.
    dbPool, err := sql.Open("mysql", dbURI)
    if err != nil {
    	return nil, fmt.Errorf("sql.Open: %v", err)
    }

    // ...

    return dbPool, nil
このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub にあるソースコードを表示してください。

ベスト プラクティスとその他の情報

アプリケーションをローカルでテストする場合、Cloud SQL プロキシを使用できます。詳細については、ローカルテストにプロキシを使用する場合のクイックスタートをご覧ください。

接続プール

データベース サーバー自体、または基盤となるインフラストラクチャによって、基盤となるデータベースへの接続が切断される可能性があります。これを軽減するには、接続プールと自動再接続をサポートするクライアント ライブラリを使用することをおすすめします。

接続プールの使用方法の詳しい例については、データベース接続を管理するをご覧ください。

接続上限

Cloud SQL では、同時接続の上限が設定されています。これらの上限は、選択したデータベース エンジンによって異なります。詳しくは、Cloud SQL の割り当てと上限をご覧ください。

App Engine には負荷の増加に応じて自動的にインスタンスを作成する機能があるため、これらの上限を超える可能性があります。この問題を回避するには、App Engine インスタンスの最大数を制限します。詳しくは、要素のスケーリングをご覧ください。

スタンダード環境で実行される App Engine の各インスタンスでは、インスタンスに対する同時接続数が最大 100 個に制限されます。PHP 5.5 アプリについては、同時接続数が最大 60 個に制限されます。

App Engine アプリケーションでは、使用状況や環境に応じてリクエストに時間制限が設けられる場合があります。詳しくは、App Engine のスタンダード環境とフレキシブル環境におけるインスタンスの管理方法をご覧ください。

さらに App Engine アプリケーションには、App Engine の割り当てページで説明されている App Engine の割り当てと上限の追加も適用されます。