2016-12-03 135 views
0

爱堆栈,我的第一篇完整的出无奈。感谢您的意见!透过App Engine(第二代CLOUDSQL)连接到CLOUDSQL GO

  • 创建App Engine的项目
  • 创建的第二代MySQL实例在我的App Engine专案
  • 创建的数据库的MySQL实例
  • 在App Engine中,我激活 - >谷歌云壳牌< - - 。 (我在我的console.cloud.google.com的命令提示符下工作)

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

我建立并运行它。 go build mysqlexample.go ./mysqlexample

我还没有能够实现成功的连接。你可以看到我尝试过的所有不同的连接字符串,它们的右边是我得到的响应。

我可以使用mysql管理员从本地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:[email protected](copiedPastedInstanceConnectionName)/d‌​atabaseName?charset=‌​charset&collation=co‌​llation&tls=tlsConfi‌​gName&parseTime=true 
    //First Generation Connection String  
     //username:[email protected](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!") 
    } 

} 
+0

,如果你从App Engine的标准或App Engine的连接Flex你没有说。我怀疑你是从App Engine Flex连接的,但是阅读App Engine Standard文档/帖子。请确认。 – Vadim

+0

我正在Google Cloud Shell中工作。制作程序,构建它,运行它。在部署解决方案并将其添加到yaml之前,我还没有选择使用Flex。我一直在做所有GO例子,我一直在做这个云壳环境。现在我想和云端SQL进行交谈并陷入困境。现在我认为我正在与谷歌云壳做斗争。我将部署我的应用程序并在今晚打开flex并发布结果。下面的连接字符串在云外壳中不起作用,但至少flex连接字符串给了我一个新消息...没有这样的文件目录 –

+0

你应该在你的文章中更清楚地说明。在这种情况下,您应该不**遵循App Engine指令,因为它们用于从App Engine进行连接。从云端连接Shell有点复杂,您需要在shell中下载并运行Cloud SQL Proxy以便连接(使用我从App Engine Flex发布的相同连接字符串) – Vadim

回答

7

以下是正确的连接字符串,但它们之间的区别,这取决于应用程序引擎的版本,你是从连接。

App Engine的标准:

user:[email protected](INSTANCE_CONNECTION_NAME)/dbname 

App Engine的灵活性:

user:[email protected](/cloudsql/INSTANCE_CONNECTION_NAME)/dbname 
+0

谢谢Vadim,您的指导帮助并且我已经在部署的应用程序引擎Flex环境中使用了unix连接字符串。我仍然在Google Cloud Shell上遭到封锁,但我很高兴能够实现这一目标。这是我通过搜索您的示例连接字符串得到的谷歌文档中最有用的页面。 https://cloud.google.com/appengine/docs/flexible/go/using-cloud-sql –

1

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

为新人们去,App Engine和CLOUDSQL只是写的简单的GO程序连接和与您的CloudSQL第二代数据库进行通信令人沮丧!

您可以选择制作App Eng或App Eng Flex,SQL第1代或第2代....根据组合连接字符串的不同而不同。所有谷歌的文档,当你搜索驱动你第一代SQL和App引擎没有弯曲,因为这是主要在生产中。确保你正在阅读Flex文档,如果你这样做。确保你正在阅读第二代文档,如果这样做。有时,他们是完全不同的文档,有时文件堆叠在页面上,你必须转到底部看到更新的东西,第二代SQL和应用工程弯曲。

CloudShell很棘手,我仍然无法编译GO并在此处与SQL进行交谈。我成功地从一个已部署的应用程序引擎flex与SQL PROXY RUNNING交谈到云数据库第二代,您必须使用SQL PROXY。你必须通过设置来为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") 
} 

}