【问题标题】:Connecting to CloudSQL from App Engine (Second Generation CloudSQL) GO从 App Engine(第二代 CloudSQL)GO 连接到 CloudSQL
【发布时间】:2017-04-18 00:10:08
【问题描述】:

Love the Stack,我第一次发帖是出于完全的挫败感。谢谢你们!

  • 已创建 App Engine 项目
  • 在我的 App Engine 项目中创建了第二代 MySQL 实例
  • 在 MySQL 实例中创建数据库
  • 在 App Engine 中,我激活了 --> Google Cloud Shell

我已经复制了这个基本的 GO 程序来连接我的 MySQL 实例。

我构建并运行它。 去构建 mysqlexample.go ./mysql示例

我无法成功连接。您可以看到我尝试过的所有各种连接字符串,它们的右侧是我得到的响应。

我可以使用 mysql admin 从本地 Windows 机器进行连接。

帮助?

package main

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "log"
    )

func main() {

    const dbIP = "104.xxx.xx.x"
    const dbInstanceName =  "esp-1-dev:us-central1:espdev"
    const dbName = "servpro"
    const dbUserName = "root"
    const dbPassword = "xxxxxxx"

    const dbOpenString = dbUserName + ":" + dbPassword + "@/" + dbInstanceName + "/" + dbName  //GETS RESPONSE default addr for network 'AppEngine:Zone:Project' unknown
    //const dbOpenString = dbUserName + "@cloudsql(" + dbInstanceName + ")/" + dbName   //GETS RESPONSE  dial cloudsql: unknown network cloudsql
    //const dbOpenString = dbUserName + "@/"  //+ "?parseTime=true&loc=UTC"                 //GETS RESPONSE  getsockopt: connection refused
    //const dbOpenString = dbUserName + ":" + dbPassword + "@tcp(" + dbIP + ":3306)/" + dbName  //GETS RESPONSE  dial tcp 104.xxx.xxx.x:3306: getsockopt: connection timed out

    //  Got this from stack overflow.  GoDocs are not updated to reflect 2nd Gen databases.
    //  http://stackoverflow.com/questions/38890022/tls-requested-but-server-does-not-support-tls-error-with-google-cloud-sql-2nd
    //user:password@cloudsql(copiedPastedInstanceConnectionName)/d‌​atabaseName?charset=‌​charset&collation=co‌​llation&tls=tlsConfi‌​gName&parseTime=true
    //First Generation Connection String    
        //username:password@cloudsql(appID:CloudSQLInstance)/databasename?parseTime=true&loc=UTC

    db, err := sql.Open("mysql", dbOpenString);
    defer db.Close()

    log.Println("Attempting Ping of database....")

    err = db.Ping()

    if err != nil {
        log.Println("db.Ping() failed:  " + dbOpenString)
        log.Println(err)
    } else {
        log.Println("Success!")
    }

}

【问题讨论】:

  • 您没有说您是从 App Engine Standard 还是 App Engine Flex 进行连接。我怀疑您是从 App Engine Flex 连接的,但正在阅读 App Engine 标准文档/帖子。请确认。
  • 我在 Google Cloud Shell 中工作。制作程序,构建它,运行它。在部署解决方案并将其添加到 yaml 之前,我还没有使用 Flex 的选项。在处理所有 GO 示例时,我一直在做这个云 shell 环境。现在我想和云 sql 交谈并被卡住。我想现在我正在与谷歌云壳作斗争。今晚我将部署我的应用程序并打开 flex 并发布结果。下面的连接字符串在 cloud shell 中不起作用,但至少 flex 连接字符串给了我一条新消息……没有这样的文件目录
  • 您应该在帖子中更清楚地说明这一点。在这种情况下,您应该遵循 App Engine 说明,因为它们是从 App Engine 连接的。从 Cloud Shell 连接有点复杂,您需要在 shell 中下载并运行 Cloud SQL 代理才能连接(使用我从 App Engine Flex 发布的相同连接字符串)

标签: google-app-engine go google-cloud-sql


【解决方案1】:

以下是正确的连接字符串,但它们会因您连接的 App Engine 版本而异。

App Engine 标准:

user:password@cloudsql(INSTANCE_CONNECTION_NAME)/dbname

App Engine 灵活:

user:password@unix(/cloudsql/INSTANCE_CONNECTION_NAME)/dbname

【讨论】:

  • 感谢 Vadim,您的指导对我有帮助,我的 unix 连接字符串在已部署的应用程序引擎 flex 环境中工作。我仍然在 Google Cloud Shell 上被阻止,但我很高兴能正常工作。这是我通过搜索您的示例连接字符串得到的谷歌文档中最有用的页面。 cloud.google.com/appengine/docs/flexible/go/using-cloud-sql
【解决方案2】:

如果您要迁移到第二代 Go App Engine (Golang 1.11),请将您的连接字符串从:

user:password@cloudsql(instanceID)/db

user:password@unix(/cloudsql/instanceID)/db

【讨论】:

    【解决方案3】:

    https://cloud.google.com/appengine/docs/flexible/go/using-cloud-sql

    对于刚接触 GO、App Engine 和 CloudSQL 的新手来说,仅仅编写最简单的 GO 程序来连接 CloudSQL 2nd Gen 数据库并与之通信是令人沮丧的!

    您可以选择,App Eng 或 App Eng Flex,SQL 1st 或 2nd Gen.... 取决于组合,连接字符串会有所不同。当您搜索时,所有 google 的文档都会驱使您使用不带 flex 的第一代 SQL 和 App Engine,因为这主要用于生产。如果您这样做,请确保您正在阅读 Flex 文档。如果这样做,请确保您正在阅读 2nd Gen 文档。有时它们是完全不同的文档,有时文档堆叠在一个页面上,您必须深入到底部才能看到较新的东西 2nd gen sql 和 app eng flex。

    CloudShell 很棘手,我仍然无法编译 GO 并在这里与 SQL 2nd 对话。我正在从已部署的应用程序引擎 flex 中成功地与 cloud sql 2nd gen 交谈,并运行 SQL 代理,您必须使用 SQL 代理。您必须在 appengine 和 SQL 上完成此创建用户的设置。

    这是我的工作程序。

    package main
    
    import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "log"
    "fmt"
    "net/http"
    )
    
    func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "ok")
    }
    
    func main() {
    http.HandleFunc("/", handle)
    http.HandleFunc("/_cloudshellProxy/_ah/health", healthCheckHandler)
    log.Print("Listening on port 8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
    }
    
    
    func handle(w http.ResponseWriter, r *http.Request) {
    
    const dbIP = "104.xxx.xxx.x"
    const dbInstanceName =  "projectname:us-central1:sqlinstance"
    const dbName = "servxxx"
    const dbUserName = "sqlproxysuser"
    const dbPassword = "xxxRockxxx"
    
    
    if r.URL.Path != "/" {
        http.NotFound(w, r)
        return
    }
    fmt.Fprint(w, "Hello SQL!  Hello?")
    fmt.Fprint(w, "\n")
    
    const dbOpenString = dbUserName + ":" + dbPassword + "@unix(/cloudsql/" + dbInstanceName + ")/" + dbName 
    //const dbOpenString = dbUserName + ":" + dbPassword + "@cloudsql(" + dbInstanceName + ")/" + dbName 
    
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    //-=- SQL OPEN Statement,  per docs, DOES NOT return an error ever
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    db, err := sql.Open("mysql", dbOpenString);
    defer db.Close()
    
    err = db.Ping()
    if err != nil {
        fmt.Fprint(w, "Failed Connection" + "  " + dbOpenString)
        fmt.Fprint(w, "\n")
        fmt.Fprint(w, err)
        return
    } else {
        fmt.Fprint(w, "SUCCESSFUL CONNECTION" + "  " + dbOpenString)
        fmt.Fprint(w, "\n")
    }
    
    _, err = db.Exec("CREATE TABLE IF NOT EXISTS exercisecloudsql101 (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, description TEXT, PRIMARY KEY (id))")
    if err != nil {
        fmt.Fprint(w, "CREATE TABLE failed:")
        fmt.Fprint(w, "\n")
        fmt.Fprint(w, err) 
        fmt.Fprint(w, "\n")
    } else {
        fmt.Fprint(w, "SUCCESSFUL CreateTable" + "  " + dbOpenString)
        fmt.Fprint(w, "\n")
    }
    
    }
    

    【讨论】:

      【解决方案4】:

      在连接到云 SQL 实例时遇到了同样的问题。下面是我在 Windows localhost 环境中工作的一种变体。我的 localhost 的 IP 需要添加到数据库实例的授权网络中。

      Windows localhost 通过 tcp 连接:

      user:password@tcp(104.xxx.xxx.xxx:3306)/dbname
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-25
        • 2013-07-15
        • 2020-04-05
        • 2019-05-19
        • 1970-01-01
        相关资源
        最近更新 更多