我正在使用 gin 框架来开发我的 go 微服务。 我使用谷歌云作为提供商,并使用谷歌云运行来部署微服务和谷歌云 postgressql 作为数据库。 我正在使用 IAM 身份验证。
下面是我用于创建数据库对象的代码
func connectDatabase() (*gorm.DB, error) {
fmt.Println("Connecting to database")
// Construct the DSN
dsn := fmt.Sprintf("host=%s dbname=%s user=%s sslmode=disable",
os.Getenv("INSTANCE_CONNECTION_NAME"), // Cloud SQL instance connection name
os.Getenv("DB_NAME"), // Database name
os.Getenv("DB_USER"), // Database password
)
// Open a connection to the database
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
return nil, fmt.Errorf("error connecting to database: %w", err)
}
// Auto-migrate your models
db.AutoMigrate(&User{})
fmt.Println("Connected to database successfully")
return db, nil
}
下面是我用于部署微服务的cmd
gcloud run deploy api \
--source=. \
--set-env-vars INSTANCE_CONNECTION_NAME=“env-xxxx:us-west1:uxxx” \
--set-env-vars DB_NAME=“dbxxxxxx” \
--set-env-vars DB_USER="[email protected]" \
--service-account="[email protected]" \
--allow-unauthenticated
使用上面的代码,部署微服务后,我收到错误“[0m[31m[error] [0m无法初始化数据库,出现错误无法连接到
host=sxxxx-xxxxx:us-west1:uxxx [email protected] database= dbxxxxxx
:主机名解析错误(查找 sxxxx-xxxx:us -west1:uxxxx: 没有这样的主机)”
我假设您使用的是公共IP。
您有几种选择来执行此操作:
package main
import (
"fmt"
"time"
"cloud.google.com/go/cloudsqlconn"
"cloud.google.com/go/cloudsqlconn/postgres/pgxv5"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func main() {
cleanup, err := pgxv5.RegisterDriver(
"cloudsql-postgres",
cloudsqlconn.WithLazyRefresh(),
cloudsqlconn.WithIAMAuthN(),
)
if err != nil {
panic(err)
}
// cleanup will stop the driver from retrieving ephemeral certificates
// Don't call cleanup until you're done with your database connections
defer cleanup()
dsn := "host=my-project:us-central1:my-instance user=postgres password=postgres dbname=postgres sslmode=disable"
db, err := gorm.Open(postgres.New(postgres.Config{
DriverName: "cloudsql-postgres",
DSN: dsn,
}))
if err != nil {
panic(err)
}
// get the underlying *sql.DB type to verify the connection
sdb, err := db.DB()
if err != nil {
panic(err)
}
var t time.Time
if err := sdb.QueryRow("select now()").Scan(&t); err != nil {
panic(err)
}
fmt.Println(t)
}
从方便的角度来看,#2 更容易。请注意“延迟刷新”选项,该选项可确保 Go Connector 不会尝试在请求之外运行后台 goroutine,因为 Cloud Run 默认情况下会限制 CPU 并导致后台 goroutine 出现问题。