You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cloud Run中执行Go Migrate连接Cloud SQL遭拒绝问题排查

问题分析与解决方案

一、数据库URI格式错误

你用的postgres://{user}:{password}@cloudsql/{host}:{port}/{db_name}格式完全不对,Cloud Run连接Cloud SQL(PostgreSQL)的正确URI分两种场景:

  1. Unix套接字连接(推荐,无需额外端口)
    正确格式是:
postgres://{user}:{password}@/{db_name}?host=/cloudsql/{connection_name}

这里的{connection_name}就是你的project-name:region-name:instance-name,这种方式通过Cloud Run挂载的Unix套接字直接对接Cloud SQL,不需要指定端口。

  1. TCP连接(需搭配Cloud SQL Auth Proxy)
    如果要走TCP,得先在容器内启动Cloud SQL Auth Proxy,此时URI要指向代理的本地端口(默认5432):
postgres://{user}:{password}@127.0.0.1:5432/{db_name}

但这种方式需要在Dockerfile里添加代理的下载、启动命令,不如Unix套接字简洁。

二、Cloud Run配置遗漏项

你大概率没做这两个关键配置:

  • 部署时必须关联Cloud SQL实例:用CLI部署要加--add-cloudsql-instances={connection_name}参数;在Cloud Console里配置Cloud Run服务时,找到「Cloud SQL连接」选项添加你的实例。
  • 给Cloud Run服务账号加权限:确保服务账号拥有Cloud SQL Client角色,否则连不上Cloud SQL。

三、Go项目数据库迁移的更优方案

1. 部署流程中独立执行迁移(推荐)

别把迁移和应用启动绑在一起,直接在GitHub Action部署流程里单独跑迁移:

  • 在Action中用Cloud SQL Auth Proxy连接Cloud SQL,再执行golang migrate命令。
  • 这样能在部署前验证迁移是否成功,不会因为迁移失败导致应用启动炸锅。
  • 核心Action步骤示例:
    - name: Run DB migrations
      env:
        DB_URI: postgres://${{ secrets.DB_USER }}:${{ secrets.DB_PASSWORD }}@127.0.0.1:5432/${{ secrets.DB_NAME }}
      run: |
        # 下载Cloud SQL Auth Proxy
        wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
        chmod +x cloud_sql_proxy
        # 启动代理后台运行
        ./cloud_sql_proxy -instances=${{ secrets.CLOUD_SQL_CONNECTION_NAME }}=tcp:5432 &
        # 等待代理初始化
        sleep 5
        # 执行迁移
        migrate -database "$DB_URI" -path ./migrations up
    

2. 应用内迁移的改进(如果坚持要在启动时跑)

  • 加连接重试逻辑:数据库连接可能因网络延迟失败,不要一次性报错退出,循环重试几次。
  • 用正确的DSN格式,比如Unix套接字的写法:
    import (
      "database/sql"
      "fmt"
      "os"
      _ "github.com/lib/pq"
    )
    
    func getDB() (*sql.DB, error) {
      dsn := fmt.Sprintf("postgres://%s:%s@/%s?host=/cloudsql/%s",
        os.Getenv("DB_USER"),
        os.Getenv("DB_PASSWORD"),
        os.Getenv("DB_NAME"),
        os.Getenv("CLOUD_SQL_CONNECTION_NAME"),
      )
      return sql.Open("postgres", dsn)
    }
    

四、代码片段补充提醒

虽然没看到你的代码截图,但要注意:

  • 所有数据库凭证、连接名都通过Cloud Run环境变量传递,别硬编码。
  • 连接数据库时加上上下文超时,避免无限等待。

内容的提问来源于stack exchange,提问作者Fidriyanto Rizkillah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:05:05