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

Go语言gRPC服务部署Cloud Run失败:数据库连接超时求助

问题

尝试将Go语言编写的gRPC服务部署到Cloud Run时,始终收到如下启动错误:

The user-provided container failed to start and listen on the port defined provided by the PORT=5000 environment variable

服务在本地运行正常,且网上同类型示例代码可正常部署。

更新: 查看GCP日志后定位到根因:数据库连接环节失败,client.Schema.Create(context.Background())执行报错,日志内容为:

failed creating schema resources: querying server version dial tcp <ip_address>:5432: connect: connection timed out

已配置Cloud Run与数据库的关联(附截图)。

相关代码

main.go

client, err := ent.Open("postgres database")
if err != nil {
    log.Fatalf("failed opening connection to postgres: %v", err)
}
defer client.Close()

if err := client.Schema.Create(context.Background()); err != nil {
    log.Fatalf("failed creating schema resources: %v", err)
}

server := grpc.NewServer()

// Register services
// ...
    
lis, err := net.Listen("tcp", ":5000")
if err != nil {
    log.Fatalf("failed listening: %s", err)
}

if err := server.Serve(lis); err != nil {
    log.Fatalf("server ended: %s", err)
}

Dockerfile

FROM golang:1.21

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . ./

RUN CGO_ENABLED=0 GOOS=linux go build -o /pm_backend

EXPOSE 5000

CMD ["/pm_backend"]

Cloud Run设置(英文截图翻译)

  • 容器端口:5000
  • 环境变量:PORT=5000
  • Cloud SQL连接:已启用,关联目标PostgreSQL实例
  • 服务账号:使用默认服务账号
  • 启动超时:默认5分钟

解决方案

1. 修复数据库连接超时问题

(1)使用Cloud SQL专属连接方式

不要直接通过公网IP连接Cloud SQL,Cloud Run应通过Unix套接字建立连接,修改ent.Open的连接字符串:

// 替换为你的项目ID、区域、实例名、数据库账号密码
connStr := "host=/cloudsql/<PROJECT_ID>:<REGION>:<INSTANCE_NAME> user=<DB_USER> password=<DB_PWD> dbname=<DB_NAME> sslmode=disable"
client, err := ent.Open("postgres", connStr)

建议通过环境变量注入敏感信息(如密码、实例名),避免硬编码。

(2)验证权限配置

  • 确认Cloud Run服务使用的账号已被授予Cloud SQL客户端角色:在IAM控制台中找到该服务账号,添加roles/cloudsql.client角色。
  • 若使用私有IP连接,需确保Cloud Run服务与Cloud SQL实例在同一VPC网络中,或已配置VPC peering。

(3)调整启动超时

Schema创建可能需要较长时间,在Cloud Run服务的「容器」设置页,将「启动超时」从默认5分钟调整为更大值(如10分钟),避免初始化过程被中断。

2. 规范端口监听逻辑

原始错误提示端口问题,需确保代码监听Cloud Run提供的PORT环境变量,而非硬编码:

import "os"

// ...

port := os.Getenv("PORT")
if port == "" {
    port = "5000" // 本地开发默认值
}
lis, err := net.Listen("tcp", ":"+port)

Dockerfile中的EXPOSE 5000仅为声明,实际监听端口需与Cloud Run的PORT环境变量一致。

3. 调试技巧

  • 在代码中添加日志输出连接参数(注意隐藏密码等敏感信息),确认连接配置是否正确。
  • 本地使用Cloud SQL Auth Proxy模拟Cloud Run环境,测试数据库连接与Schema创建流程,排查本地与云端的差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:15:03