我已经尝试了很多事情,但在尝试从我的Google Cloud App Engine连接到Google Cloud PostgreSQL实例时,似乎无法通过Exception while connecting
。
这可能是我作为开发人员处理过的最令人沮丧的事情。连接到数据库应该不难。
我做错了什么?
不起作用的事情:
- 如何通过Google App Engine Flex将Google Cloud SQL连接到僵尸网络核心应用程序?
- 无法从谷歌应用引擎节点连接到云SQL中的postgres 。
- https://cloud.google.com/sql/docs/postgres/connect-app-engine-flexible
- https://github.com/GoogleCloudPlatform/dotnet-docs-samples/tree/master/appengine/flexible/CloudSql
app.yaml:
runtime: custom
env: flex
beta_settings:
cloud_sql_instances: "<project-id>:<region>:<sql-instance>=tcp:5432"
使用的最终连接字符串:
Uid=<db_user>;Pwd=<db_password>;Host=cloudsql;Database=<db_name>
// other attempts:
Uid=<db_user>;Pwd=<db_password>;Host=cloudsql;Database=<db_name>;Port=5432
Uid=<db_user>;Pwd=<db_password>;Host=/cloudsql/<project-id>:<region>:<sql-instance>;Database=<db_name>
Uid=<db_user>;Pwd=<db_password>;Host='/cloudsql/<project-id>:<region>:<sql-instance>';Database=<db_name>
Uid=<db_user>;Pwd=<db_password>;Server='/cloudsql/<project-id>:<region>:<sql-instance>';Database=<db_name>
用法:
var connectionString = new NpgsqlConnectionStringBuilder(<connection string>)
{
SslMode = SslMode.Disable
};
NpgsqlConnection connection =
new NpgsqlConnection(connectionString.ConnectionString);
connection.Open();
相关堆栈跟踪:
Exception while connecting
at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.ConnectorPool.AllocateLong(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlConnection.<>c__DisplayClass32_0.<g__OpenLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Npgsql.NpgsqlConnection.Open()
Dockerfile(也许这很重要,因为我在我的app.yaml
runtime
中使用custom
?
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 8080
EXPOSE 443
ENV ASPNETCORE_URLS=http://*:8080
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
COPY . /src
WORKDIR /src
RUN dotnet restore --packages /packages
RUN dotnet publish -c Release -o /published
FROM base AS final
COPY --from=build /published /app/
WORKDIR /app
ENTRYPOINT [ "dotnet", "myapp.dll" ]
部署脚本:
gcloud beta app deploy --project <project-id>
编辑:
从云控制台检查我的 sql 实例的 PostgreSQL 错误,我在最后一个Exception while connecting
错误之前看到以下错误:
System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (99): Cannot assign requested address /cloudsql/<my connection instance id>/.s.PGSQL.5432
您是否在这里查看了Cloud SQL的示例应用程序?
更新:
很难确定出了什么问题,因为您提供了几个不同的选项,并且不清楚哪些组合提供了哪些错误。但是,基本上有两种不同的连接方式,重要的是您的代码与app.yaml
中的配置相匹配:
通过 TCP 端口连接
要通过 TCP 端口进行连接,请在app.yaml
中使用以下内容:
beta_settings:
cloud_sql_instances: "<PROJECT_ID>:<REGION_ID>:<INSTANCE_ID>=tcp:5432"
然后对连接字符串使用以下格式:
"Host=172.17.0.1;Uid=<DB_USER>;Pwd=<DB_PASS>;Database=<DB_NAME>"
请注意,部署到 Flex 时Host=172.17.0.1;
是 IP,但如果在本地使用 Cloud SQL 代理,则会127.0.0.1
IP。
通过 Unix 域套接字连接
要通过 Unix 套接字进行连接,请在app.yaml
中使用以下内容:
beta_settings:
cloud_sql_instances: "<PROJECT_ID>:<REGION_ID>:<INSTANCE_ID>"
然后对连接字符串使用以下格式:
"Server=/cloudsql/<PROJECT_ID>:<REGION_ID>:<INSTANCE_ID>/.s.PGSQL.5432;Uid=<DB_USER>;Pwd=<DB_PASS>;Database=<DB_NAME>"
注意:您的驱动程序可能会自动添加/.s.PGSQL.5432
- 有些可以,有些不会。
故障 排除
如果您确定app.yaml
和代码正确匹配,但仍收到超时消息,则下一步是检查应用程序日志。您可以使用 Stackdriver 并按appengine.googleapis.com/cloud_sql_proxy
筛选,以便仅查看实例的日志。
一些常见的错误是:
- 实例没有公网 IP(私网 IP 连接步骤不同(
- 云 SQL 管理员 API 未在应用引擎所在的项目中启用
- 所使用的服务账户(默认值为
service-PROJECT_NUMBER@gae-api-prod.google.com.iam.gserviceaccount.com
(没有数据库所在项目的Cloud SQL Client
IAM 角色或更高级别的角色
在五次检查我是否遵循了 kurtisvg 答案中给出的所有步骤并且仍然没有任何进展之后,对我来说,解决方案就像停止 App Engine 版本并重新启动它一样简单。大概在重新启动版本之前,我为解决问题而更改的任何设置都不会应用。