【发布时间】:2020-10-07 07:49:34
【问题描述】:
我可以使用 unix 套接字从 Cloud Run 连接到 Cloud Postgresql,并且可以成功查询数据库。但是,如果我关闭连接并尝试打开新连接,整个过程会挂起,最终 Cloud Run 调用会超时(如预期的那样在 900 秒)。
详情: 我正在使用 Dart postgres-dart 库连接到数据库。我有一个实现连接池的库的包装器。在本地,一切正常:应用程序可以创建连接、查询数据库、关闭连接、处理数据、创建新连接、将一些结果写回数据库,然后再次关闭连接。
但是,在 Cloud Run 上,应用程序会创建第一个连接、查询数据库、关闭连接、处理数据并尝试创建新连接。这是一切都挂起并最终 Cloud Run 调用超时的地方。
没有抛出任何错误,也没有其他迹象表明我发现出了问题。
Cloud Run 是否有可能只提供一次连接,并且必须保持打开状态并在整个调用过程中重复使用?鉴于 Dart 的异步特性,最好根据需要完成的工作创建连接,而不是阻塞数据库调用。如果连接根据工作负载的性质保持打开状态,这似乎也是一种资源浪费。我知道我可以限制 Cloud Run 实例的数量来限制数据库连接,但是如果有一个长时间运行的进程,这无助于资源占用。但也许我在 Cloud Run 的预期工作方式上遗漏了一些东西。
除此之外,我很困惑,因为它在 Cloud Run 之外运行良好,并且有关于正在发生的事情的错误消息。任何有关确认 Cloud Run 连接如何工作或如何在 Cloud Run 上诊断问题的帮助都非常感谢。
编辑
我创建了一个简化的 Cloud Run 端点,它也出现了同样的问题。该库是我在 postgres-dart 之上编写的,称为 stanza。
这个例子非常简单——它只是尝试做同样的事情两次,但完全相同的代码不会第二次运行......
Future<Response> socketTest(Request req) async {
final keys = Keys();
final testTable = TestTable.$table;
final select = SelectQuery(testTable)
..selectFields([testTable.textField, testTable.intField])
..orderBy(testTable.id)
..limit(1);
final creds = PostgresCredentials(keys.runDbHost, keys.runDbPort, keys.dbDatabase, keys.dbUser, keys.dbPassword);
final stanza = Stanza.unix(creds, maxConnections: 5);
final c1 = await stanza.connection();
final r1 = await c1.execute<TestTable>(select);
final out1 = r1.first.value;
print('${out1.textField} | ${out1.intField}'); // works :)
final c2 = await stanza.connection();
final r2 = await c2.execute<TestTable>(select); // hangs :(
final out2 = r2.first.value; // never reaches here
print('${out2.textField} | ${out2.intField}');
return req.response.send.code(200);
}
Cloud Run 配置了 Postgresql 实例作为连接,服务帐户具有 Cloud SQL Client 权限,并添加了必要的环境变量。套接字位置是 /cloudsql/PROJECT:REGION:INSTANCE/.s.PGSQL.5432
我的下一步是用更少的抽象层来尝试这种连接,看看我是否可以让它工作。但是,当在本地同一容器中运行时,此代码可以正常工作。
【问题讨论】:
-
您是否按照有关如何从云运行连接的文档? cloud.google.com/sql/docs/postgres/connect-run#connection-pools,我想你也可以看看这个cloud.google.com/sql/docs/postgres/…
-
谢谢你,哈里夫。是的,我遵循了连接文档,它在 Cloud Run 中成功运行,我可以在其中创建第一个连接并查询数据库,但只能创建第一个连接。使用 Cloud SQL 代理和 unix 套接字在本地容器中打开和关闭连接。构建中没有任何变化——只是部署到 Cloud Run 中不起作用。
-
我明白了,你能分享一下你处理连接的代码的 sn-p 吗?
-
您能否分享您的一段代码(用于数据库连接)以及如何部署/配置您的云运行服务?
-
@Kirk 我遇到了同样的问题。只是第一次工作。我们能找到原因吗?
标签: google-cloud-platform google-cloud-sql google-cloud-run