Como se conectar do ambiente padrão do App Engine ao Cloud SQL

Esta página contém informações e exemplos para se conectar a uma instância do Cloud SQL a partir de um serviço em execução no ambiente padrão do App Engine.

O Cloud SQL é um serviço de banco de dados totalmente gerenciado que facilita a configuração, a manutenção, o gerenciamento e a administração dos bancos de dados relacionais na nuvem.

O App Engine é uma plataforma sem servidor totalmente gerenciada para desenvolver e hospedar aplicativos da Web em grande escala. É possível escolher entre várias linguagens, frameworks e bibliotecas conhecidos para desenvolver seus apps e, em seguida, permitir que o App Engine provisione os servidores e escalone as instâncias de app com base na demanda.

Como configurar uma instância do Cloud SQL

  1. Ative a API Cloud SQL Admin no projeto do qual você está se conectando, caso ainda não tenha feito isso:

    Ative a API

  2. Crie uma instância do Cloud SQL para MySQL.

    Por padrão, o Cloud SQL atribui um endereço IP público a uma nova instância. Você também tem a opção de atribuir um endereço IP particular. Para mais informações sobre as opções de conectividade de ambos, consulte a página Visão geral da conexão .

Como configurar o App Engine

As etapas para configurar o ambiente padrão do App Engine dependem do tipo de endereço IP atribuído à instância do Cloud SQL.

IP público (padrão)

Para configurar o ambiente padrão do App Engine para ativar conexões com uma instância do Cloud SQL usando IP público:

  • Verifique se a instância criada acima tem um endereço IP público. Isso pode ser visto na página Visão geral da sua instância no Console do Google Cloud. Se precisar adicionar um, consulte a página Como configurar o IP público para ver instruções.
  • Receba o INSTANCE_CONNECTION_NAME da instância. Isso pode ser encontrado na página Visão geral da instância no Console do Google Cloud ou executando o seguinte comando: gcloud sql instances describe [INSTANCE_NAME].
  • Verifique se a conta de serviço usada pelo app para autenticar chamadas para o Cloud SQL tem o papel e as permissões apropriados do Cloud SQL.
    • A conta de serviço do seu serviço precisa de um dos seguintes papéis do IAM:
      • Cloud SQL Client (recomendável)
      • Cloud SQL Editor
      • Cloud SQL Admin
      Também é possível atribuir manualmente as seguintes permissões do IAM:
      • cloudsql.instances.connect
      • cloudsql.instances.get
      Para receber instruções detalhadas sobre como adicionar papéis do IAM a uma conta de serviço, consulte Como conceder papéis a contas de serviço.

    Por padrão, o app autoriza as conexões usando uma conta de serviço do App Engine. A identidade da conta de serviço está no formato PROJECT_ID@appspot.gserviceaccount.com.

    Se a conta de serviço de autorização pertencer a um projeto diferente da instância do Cloud SQL, as permissões da API Cloud SQL Admin e do IAM precisarão ser adicionadas aos dois projetos.

IP particular

Um conector de acesso VPC sem servidor processa a comunicação com sua rede VPC. Para se conectar diretamente ao IP particular, você precisa:

  1. verificar se a instância do Cloud SQL criada acima tem um endereço IP particular. Se você precisar adicionar um, consulte a página Como configurar o IP particular para ver instruções.
  2. criar um conector de acesso VPC sem servidor na mesma rede VPC da sua instância do Cloud SQL.
  3. Um conector precisa estar no mesmo projeto e região que o recurso que o utiliza, mas pode enviar tráfego para recursos em diferentes regiões.

    O acesso VPC sem servidor é compatível com a comunicação com redes VPC conectadas por meio do Cloud VPN e de peering de rede VPC.

    No entanto, esse acesso não é compatível com redes legadas ou VPC compartilhada.

  4. Configure o App Engine para usar o conector.
  5. Conecte-se usando o IP particular e a porta 3306 da instância.

Como se conectar ao Cloud SQL

Depois de configurar o ambiente padrão do App Engine, conecte-se à instância do Cloud SQL. O App Engine fornece um mecanismo que se conecta usando o Cloud SQL Proxy.

IP público (padrão)

Como se conectar com soquetes Unix

Depois de configurar corretamente o Cloud SQL, é possível conectar seu serviço ao soquete de domínio Unix da instância do Cloud SQL usando o formato: /cloudsql/INSTANCE_CONNECTION_NAME.

Essas conexões são criptografadas automaticamente sem qualquer configuração extra. Os exemplos de código mostrados abaixo são trechos de exemplos mais completos no site do GitHub. Clique em View on GitHub para ver mais

Python

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

# Remember - storing secrets in plaintext is potentially unsafe. Consider using
# something like https://cloud.google.com/secret-manager/docs/overview to help keep
# secrets secret.
db_user = os.environ["DB_USER"]
db_pass = os.environ["DB_PASS"]
db_name = os.environ["DB_NAME"]
db_socket_dir = os.environ.get("DB_SOCKET_DIR", "/cloudsql")
cloud_sql_connection_name = os.environ["CLOUD_SQL_CONNECTION_NAME"]

pool = sqlalchemy.create_engine(
    # Equivalent URL:
    # mysql+pymysql://<db_user>:<db_pass>@/<db_name>?unix_socket=<socket_path>/<cloud_sql_instance_name>
    sqlalchemy.engine.url.URL(
        drivername="mysql+pymysql",
        username=db_user,  # e.g. "my-database-user"
        password=db_pass,  # e.g. "my-database-password"
        database=db_name,  # e.g. "my-database-name"
        query={
            "unix_socket": "{}/{}".format(
                db_socket_dir,  # e.g. "/cloudsql"
                cloud_sql_connection_name)  # i.e "<PROJECT-NAME>:<INSTANCE-REGION>:<INSTANCE-NAME>"
        }
    ),
    # ... Specify additional properties here.

)

Java

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

// 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);

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

// Initialize the connection pool using the configuration object.
DataSource pool = new HikariDataSource(config);

Node.js

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

const createUnixSocketPool = async (config) => {
  const dbSocketPath = process.env.DB_SOCKET_PATH || "/cloudsql"

  // Establish a connection to the database
  return 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: `${dbSocketPath}/${process.env.INSTANCE_CONNECTION_NAME}`,
    // Specify additional properties here.
    ...config
  });
}

PHP

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

// // $username = 'your_db_user';
// // $password = 'yoursupersecretpassword';
// // $dbName = 'your_db_name';
// // $cloud_sql_connection_name = getenv("CLOUD_SQL_CONNECTION_NAME");
// // $hostname = "127.0.0.1"; // Only used in TCP mode.

if ($hostname) {
    // Connect using TCP
    $dsn = sprintf('mysql:dbname=%s;host=%s', $dbName, $hostname);
} else {
    // Connect using UNIX sockets
    $dsn = sprintf(
        'mysql:dbname=%s;unix_socket=/cloudsql/%s',
        $dbName,
        $cloud_sql_connection_name
    );
}

// Connect to the database.
// Here we set the connection timeout to five seconds and ask PDO to
// throw an exception if any errors occur.
$conn = new PDO($dsn, $username, $password, [
    PDO::ATTR_TIMEOUT => 5,
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);

C#

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

var connectionString = new MySqlConnectionStringBuilder(
    Configuration["CloudSql:ConnectionString"])
// ConnectionString is set in appsettings.json formatted as follows
// depending upon where your app is running:
// Running Locally ConnectionString:
// "Uid=aspnetuser;Pwd=;Host=127.0.0.1;Database=votes"
// Cloud Run ConnectionString:
// "Server=/cloudsql/your-project-id:us-central1:instance-name;Database=votes;User=;Password=;Protocol=unix"
// App Engine ConnectionString:
// "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);

Ruby

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

production:
  adapter: mysql2
  # Configure additional properties here.
  username: <%= ENV["DB_USER"] %>  # e.g. "my-database-user"
  password: <%= ENV["DB_PASS"] %> # e.g. "my-database-password"
  database: <%= ENV.fetch("DB_NAME") { "vote_production" } %>
  socket: "<%= ENV.fetch("DB_SOCKET_DIR") { '/cloudsql' } %>/<%= ENV["INSTANCE_CONNECTION_NAME"] %>"

Go

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

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

socketDir, isSet := os.LookupEnv("DB_SOCKET_DIR")
if !isSet {
	socketDir = "/cloudsql"
}

var dbURI string
dbURI = fmt.Sprintf("%s:%s@unix(/%s/%s)/%s?parseTime=true", dbUser, dbPwd, socketDir, 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

IP particular

Como se conectar com TCP

Conecte-se diretamente usando o endereço IP particular e a porta 3306 da instância.

Práticas recomendadas e outras informações

É possível usar o Cloud SQL Proxy ao testar seu aplicativo localmente. Acesse o guia de início rápido sobre como usar o proxy para testes locais e veja instruções detalhadas.

Pools de conexões

As conexões aos bancos de dados subjacentes podem ser descartadas pelo próprio servidor de banco de dados ou pela infraestrutura subjacente. Para atenuar isso, recomendamos que você use uma biblioteca de cliente que ofereça suporte a pools de conexão e à reconexão automática.

Para exemplos mais detalhados sobre como usar pools de conexão, consulte Como gerenciar conexões de banco de dados.

Limites de conexão

O Cloud SQL impõe um limite máximo de conexões simultâneas e esses limites podem variar dependendo do mecanismo de banco de dados escolhido (consulte a página "Cotas e limites" do Cloud SQL).

O App Engine pode criar automaticamente mais instâncias conforme o aumento da carga. Isso pode fazer com que você exceda esses limites. Para evitar esse problema, limite o número máximo de instâncias do App Engine. Para mais informações, consulte os Elementos de dimensionamento.

Cada instância do App Engine executada em um ambiente padrão não pode ter mais de 100 conexões simultâneas com uma instância. Nos apps em PHP 5.5, o limite é de 60 conexões simultâneas.

Os aplicativos do App Engine estão sujeitos a limites de tempo de solicitação, dependendo do uso e do ambiente. Para mais informações, veja como as instâncias são gerenciadas nos ambientes padrão e flexível do App Engine.

Os aplicativos do App Engine também estão sujeitos a outras cotas e limites, conforme descrito na página Cotas do App Engine.

Limites de cota da API

O App Engine fornece um mecanismo que se conecta usando o Cloud SQL Proxy, que usa a API Cloud SQL Admin. Os limites de cota da API se aplicam ao Cloud SQL Proxy.