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

