使用 Go on AppEngine 连接到 Google SQL Cloud 2nd generation

Connect to Google SQL Cloud 2nd generation with Go on AppEngine

我在这里看到其他帖子也有同样的问题,但是 none 的答案可能对我的情况有所帮助。我有一个 Google SQLCloud 第二代数据库,我正试图让我的 Go Appengine 应用建立连接。 我正在使用 go-sql-driver/mysql

起初我尝试使用与第一代相同的方式进行连接,只是将项目和实例名称作为参数传递:

sql.Open("mysql", "root@cloudsql(project:instance)/database"

然后我从 Cloud Console 和 注意到该区域也是必需的,所以我的连接参数现在看起来像:

sql.Open("mysql", "root@cloudsql(project:uscentral1:instance)/database"

还有密码

sql.Open("mysql", "root:password@cloudsql(project:uscentral1:instance)/database"

还是不行

我最后一次尝试是使用 SSL 连接,如 中所述,使用驱动程序文档中提供的代码:

    rootCertPool := x509.NewCertPool()
    pem, err := ioutil.ReadFile("/path/ca-cert.pem")
    if err != nil {
        log.Fatal(err)
    }
    if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
        log.Fatal("Failed to append PEM.")
    }
    clientCert := make([]tls.Certificate, 0, 1)
    certs, err := tls.LoadX509KeyPair("/path/client-cert.pem", "/path/client-key.pem")
    if err != nil {
        log.Fatal(err)
    }
    clientCert = append(clientCert, certs)
    mysql.RegisterTLSConfig("custom", &tls.Config{
        RootCAs: rootCertPool,
        Certificates: clientCert,
    })
    sql.Open("mysql","root:password@cloudsql(project:uscentral1:instance)/database?tls=custom")

也没有运气。

在这一点上,我只是 运行 不知道问题可能是什么。为了让它正常工作,有没有人做了与大多数人不同的事情?此时我不确定问题出在我的代码、驱动程序还是 CloudSQL 数据库中的某些配置。

请将以下工作示例与您的应用程序中的示例进行比较。将 INSTANCE_CONNECTION_NAME 替换为 Cloud Console 或 gcloud sql describe 中显示的 "Instance connection name"。 如果您没有注意到您的应用有任何不同,请尝试 运行 这个示例,看看您遇到了什么错误。

package hello

import (
        "database/sql"
        "fmt"
        _ "github.com/go-sql-driver/mysql"
        "net/http"
)

func init() {
        http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
        db, err := sql.Open("mysql", "root@cloudsql(INSTANCE_CONNECTION_NAME)/mysql")
        if err != nil {
                fmt.Fprintf(w, "Error constructing DB: %v", err)
                return
        }

        rows, err := db.Query("SELECT 1")
        if err != nil {
                fmt.Fprintf(w, "Error performing query: %v", err)
                return
        }
        fmt.Fprintf(w, "Success!")
        rows.Close()
}

原来我的项目没有 AppEngine 的默认凭据。控制台中的文档说,在项目创建时,AppEngine 和 Compute Engine 的默认凭据将默认创建,但是这个项目特别是前一段时间通过旧 App Engine 控制台创建的,我的假设是 Google 将 AppEngine 项目迁移到新架构上,它没有像现在创建新项目时那样创建默认凭据。 我删除了旧项目并创建了一个新项目,一切正常。我想为旧项目创建正确的凭据也可以。 我在这里留下这个答案是因为我只是依赖文档并且在检查显而易见的内容之前实际上花了很多时间。 Google Cloud Doc 人员将其记录在某处可能是个好建议。