App Engine에서 Cloud SQL로 연결

이 페이지에는 App Engine에서 실행되는 서비스에서 Cloud SQL 인스턴스에 연결하는 방법에 대한 정보와 예시가 포함되어 있습니다.

Cloud SQL은 클라우드에서 관계형 PostgreSQL과 MySQL 데이터베이스를 손쉽게 설정, 유지 및 관리할 수 있게 해주는 완전 관리형 데이터베이스 서비스입니다.

App Engine은 확장 가능한 웹 애플리케이션을 개발하고 호스팅하기 위한 완전 관리형 서버리스 플랫폼입니다. 몇 가지 자주 사용되는 언어, 라이브러리, 프레임워크 중에서 선택하여 앱을 개발한 후 App Engine에서 프로비저닝 서버를 관리하고 필요에 따라 앱 인스턴스를 확장할 수 있습니다.

Cloud SQL 인스턴스 설정

  1. MySQL용 Cloud SQL 인스턴스 만들기

  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 도메인 소켓을 사용 설정하려면 연결할 인스턴스가 하나인지 또는 여러 개인지에 따라 프로젝트의 app.yaml 파일에 다음 중 하나를 추가합니다.

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

TCP 포트 사용 설정

로컬 TCP 포트를 사용 설정하려면 연결할 인스턴스가 하나인지 또는 여러 개인지에 따라 다음 중 하나를 프로젝트의 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 인스턴스에 연결하도록 허용하거나 금지할 수 있습니다. 자세한 내용은 인증 옵션을 참조하여 인스턴스에 연결할 수 있는 사용자와 위치를 확인하세요.

서로 다른 두 가지 프로젝트의 리소스를 연결할 때는 두 프로젝트 모두에서 올바른 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의 소스 코드를 확인하세요.

자바

// 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 할당량 및 한도가 적용됩니다.