Kotlin Ktor部署GCP App Engine无法连接GCP Postgres:连接超时
问题:Ktor + Exposed连接GCP Postgres在App Engine部署失败,本地正常
症状
- 本地运行完全正常,但部署到App Engine后访问网站出现:
upstream connect error or disconnect/reset before headers. reset reason: connection termination
- GCP控制台日志抛出:
Exception in thread "main" org.postgresql.util.PSQLException: The connection attempt failed.
org.postgresql.util.PSQLException: The connection attempt failed.
定位到的代码
fun initDatabase(){ val jdbcUrl = ConfigManager.getStringProperty("postgres_db.jdbcUrl") val usr = ConfigManager.getStringProperty("postgres_db.username") val pw = ConfigManager.getStringProperty("postgres_db.password") val driver = ConfigManager.getStringProperty("postgres_db.driverClassName") db = Database.connect(jdbcUrl, driver, usr, pw) transaction(db) { SchemaUtils.createMissingTablesAndColumns(UserTable) UserTable.insert { it[email] = "wwwdddggg@gmail.com" it[passworld] = "Hello!" } } }
解决方案
不需要手动添加App Engine应用IP到SQL白名单
App Engine标准环境的IP是动态变化的,无法固定添加到白名单。正确做法是使用Cloud SQL提供的内置连接方式,无需配置IP白名单。修正JDBC URL格式
部署到App Engine时,必须使用Unix套接字格式的JDBC URL,而非本地调试用的TCP格式:jdbc:postgresql:///[你的数据库名]?cloudSqlInstance=[项目ID]:[区域]:[SQL实例名]&socketFactory=com.google.cloud.sql.postgres.SocketFactory用户名和密码可继续通过配置项传入,无需硬编码在URL中。
添加Cloud SQL Socket Factory依赖
在build.gradle.kts中添加依赖,确保应用能通过套接字连接SQL实例:implementation("com.google.cloud.sql:postgres-socket-factory:1.16.0")检查服务账号权限
确认App Engine默认服务账号([你的项目ID]@appspot.gserviceaccount.com)拥有Cloud SQL Client角色:- 进入GCP控制台IAM页面
- 找到该服务账号
- 添加
Cloud SQL Client角色并保存
代码小修正
代码中passworld拼写错误,建议改为password,避免后续业务逻辑问题。
内容的提问来源于stack exchange,提问作者Willor777
相关产品推荐
相关产品推荐

