从App Engine(第二代CloudSQL)连接到CloudSQL GO

huangapple go评论92阅读模式
英文:

Connecting to CloudSQL from App Engine (Second Generation CloudSQL) GO

问题

喜欢堆栈,我第一次发帖完全是出于沮丧。谢谢你的评论!

  • 创建了App Engine项目
  • 在我的App Engine项目中创建了第二代MySQL实例
  • 在MySQL实例中创建了数据库
  • 在App Engine中,我激活了--> Google Cloud Shell <--。(我在console.cloud.google.com的命令提示符中工作)

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

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

我无法成功连接。你可以看到我尝试的各种连接字符串,右边是我得到的响应。

我可以使用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&amp;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&amp;collation=co‌​llation&amp;tls=tlsConfi‌​gName&amp;parseTime=true
	//First Generation Connection String	
        //username:password@cloudsql(appID:CloudSQLInstance)/databasename?parseTime=true&amp;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!")
	}

}
英文:

Love the Stack, My first post out of complete frustration. Thanks for you comments!

  • Created App Engine Project
  • Created Second Generation MySQL Instance in my App Engine Project
  • Created Database in the MySQL Instance
  • In App Engine, I activate the --> Google Cloud Shell <--. ( I am working at a command prompt in my console.cloud.google.com)

I have copied this basic GO program to connect to my MySQL instance.

I build it and run it.
go build mysqlexample.go
./mysqlexample

I have not been able to achieve a successful connection. You can see all the various connection strings that I have tried and to the right of them is the response I get.

I can connect from my local windows machine using mysql admin.

Help?

package main

import (
	&quot;database/sql&quot;
	_ &quot;github.com/go-sql-driver/mysql&quot;
	&quot;log&quot;
	)

func main() {

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

	const dbOpenString = dbUserName + &quot;:&quot; + dbPassword + &quot;@/&quot; + dbInstanceName + &quot;/&quot; + dbName  //GETS RESPONSE default addr for network &#39;AppEngine:Zone:Project&#39; unknown
	//const dbOpenString = dbUserName + &quot;@cloudsql(&quot; + dbInstanceName + &quot;)/&quot; + dbName  	//GETS RESPONSE  dial cloudsql: unknown network cloudsql
	//const dbOpenString = dbUserName + &quot;@/&quot;  //+ &quot;?parseTime=true&amp;loc=UTC&quot;       			//GETS RESPONSE  getsockopt: connection refused
	//const dbOpenString = dbUserName + &quot;:&quot; + dbPassword + &quot;@tcp(&quot; + dbIP + &quot;:3306)/&quot; + 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&amp;collation=co‌​llation&amp;tls=tlsConfi‌​gName&amp;parseTime=true
	//First Generation Connection String	
        //username:password@cloudsql(appID:CloudSQLInstance)/databasename?parseTime=true&amp;loc=UTC

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

	log.Println(&quot;Attempting Ping of database....&quot;)

	err = db.Ping()

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

}

答案1

得分: 12

以下是正确的连接字符串,但根据您连接的 App Engine 版本不同,它们会有所不同。

App Engine 标准版:

user:password@cloudsql(INSTANCE_CONNECTION_NAME)/dbname

App Engine 弹性环境:

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

The following are the correct connection strings, but they differ depending on which version of App Engine you are connecting from.

App Engine Standard:

user:password@cloudsql(INSTANCE_CONNECTION_NAME)/dbname

App Engine Flexible:

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

答案2

得分: 5

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

user:password@cloudsql(instanceID)/db

更改为

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

英文:

If you are migrating to the second generation Go App Engine (Golang 1.11) change your connection string from:

user:password@cloudsql(instanceID)/db

to

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

答案3

得分: 2

以下是翻译好的内容:

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

你需要做出选择,是选择App Eng还是App Eng Flex,是选择SQL第一代还是第二代...根据不同的组合,连接字符串是不同的。当你搜索时,谷歌的所有文档都会引导你首先使用第一代SQL和App Engine,因为这是主要用于生产环境的。如果你正在使用App Eng Flex,请确保阅读Flex文档。如果你正在使用第二代文档,请确保阅读第二代文档。有时它们是完全不同的文档,有时文档会堆叠在一个页面上,你必须滚动到底部查看关于更新内容的部分,即第二代SQL和App Eng Flex。

CloudShell很棘手,我仍然无法在这里编译GO并与SQL第二代通信。我已经成功地从部署的App Engine Flex应用程序中使用SQL代理与云SQL第二代通信,你必须使用SQL代理。你必须按照设置说明进行操作,在App Engine和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

	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")
	}
}

希望对你有帮助!

英文:

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

For new people to GO, App Engine and CloudSQL just writing the simplest GO program to connect and communicate with your CloudSQL 2nd Gen database is frustrating!

You have choices to make, App Eng or App Eng Flex, SQL 1st or 2nd Gen.... Depending on the combination connection strings are different. All of google's documentation when you search drives you to first gen SQL and App Engine without flex because this is what is predominantly in production. Make sure you are reading Flex documentation if you are doing that. Make sure you are reading 2nd Gen docs if doing that. Sometimes they are entirely different docs, sometimes the documentation is stacked on a page and you have to goto the bottom to see about the newer stuff 2nd gen sql and app eng flex.

CloudShell is tricky, I still cannot compile GO and talk to SQL 2nd here. I am successfully talking to cloud sql 2nd gen from a deployed app engine flex WITH A SQL PROXY RUNNING, you have to use SQL PROXY. You have to go thru the setup for this create users on appengine and SQL.

This is my working program.

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

答案4

得分: 0

遇到了连接到云SQL实例的相同问题。我在Windows本地主机环境中找到了一个可行的变体,如下所示。我的本地主机的IP地址需要添加到数据库实例的授权网络中。

在Windows本地主机上通过TCP连接:

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

Have run in to the same problem of connecting to a cloud SQL instance. One variant that I got working on my windows localhost environment is below. The IP of my localhost needs to be added to Authorized networks for the db instance.

Windows localhost connect over tcp:

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

huangapple
  • 本文由 发表于 2016年12月3日 08:51:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/40943098.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定