为什么 App 引擎(python3 - 标准环境)在连接到云 sql -2nd Gen Mysql 实例时会生成中止连接?
Why does the App engine (python3 - standard environment) generate aborted connections when connecting to a cloud sql -2nd Gen Mysql instance?
我目前正在开发一个项目,使用 python 3.7,Django 2.1,Mysql 作为数据库。
我将其部署在 google 云应用引擎标准环境中,对于数据库,我正在使用云 SQL - MySql 第二代实例。
该应用程序运行良好,但是当我分析日志时,我看到了这些错误:
"aborted connection - Got an error reading communication packets"
在这种情况下,我的应用程序 (django) 正在关闭连接。如果我将我的应用程序配置为具有持久连接,并且我将 wait_timeout(即 60)放入云的配置中 sql,错误是:
"aborted connection - Got timeout reading communication packets".
我刚刚确定这不是 sql 云或我的应用程序配置的问题,而是应用引擎的问题。我是通过以下方式得出这个结论的:
- 如果我通过 Mysql workbench 连接到 sql 云实例,则不会中止连接
- 类似地,如果我 运行 我的应用程序在本地服务器上,但连接到云 sql(通过 cloud_sql_proxy),不会产生错误并且一切正常。
所以我的结论是,这是应用引擎如何连接到云sql实例的问题。
为什么会这样?怎么解决的?
我认为这是因为从 App Engine 应用程序到 Cloud SQL 的请求受制于以下时间和连接 limits:
- 对于 App Engine 标准环境中的应用 运行,所有数据库请求必须在 HTTP 请求计时器(大约 60 秒)内完成。对于灵活环境中的应用 运行,所有数据库请求必须在 60 分钟内完成。
- cron 任务等离线请求有 10 分钟的时间限制。
- 对云的请求 SQL 有限制,具体取决于 App Engine 模块的扩展类型以及实例可以在内存中保留(驻留)的时间。
- 标准环境中的每个 App Engine 实例 运行 与云 SQL 实例的并发连接不能超过 60 个。对于使用 Java 8 或 Go 1.8 编写的应用程序,限制为 100。
- Connection Issues: 如果您看到包含 "Aborted connection nnnn to db:" 的错误,这通常表示您的应用程序未正确终止连接。它也可能是由网络问题引起的。此错误并不意味着您的 Cloud SQL 实例存在问题。
您看到的 "Aborted connection" 消息通常是在连接未正确关闭或服务器与客户端之间存在网络异常时触发的。
有时 Cloud SQL 个实例和 GAE 有 long-live 个空闲连接。为了解决这个问题,建议将“wait_timeout”标志设置为低于 600 秒 - 正如您已经尝试过的那样。
另一种可能的解决方案是实施 application-level 保活。 SQLAlchemy 提供“pre-ping” for this. Otherwise, generate activity on all open connections by sending a simple SQL statement such as "SELECT 1;" regularly, at least once every 5 minutes. Also consider using statements in your code like “with db.connect() as conn:”来控制连接的生命周期。
我目前正在开发一个项目,使用 python 3.7,Django 2.1,Mysql 作为数据库。
我将其部署在 google 云应用引擎标准环境中,对于数据库,我正在使用云 SQL - MySql 第二代实例。
该应用程序运行良好,但是当我分析日志时,我看到了这些错误:
"aborted connection - Got an error reading communication packets"
在这种情况下,我的应用程序 (django) 正在关闭连接。如果我将我的应用程序配置为具有持久连接,并且我将 wait_timeout(即 60)放入云的配置中 sql,错误是:
"aborted connection - Got timeout reading communication packets".
我刚刚确定这不是 sql 云或我的应用程序配置的问题,而是应用引擎的问题。我是通过以下方式得出这个结论的:
- 如果我通过 Mysql workbench 连接到 sql 云实例,则不会中止连接
- 类似地,如果我 运行 我的应用程序在本地服务器上,但连接到云 sql(通过 cloud_sql_proxy),不会产生错误并且一切正常。
所以我的结论是,这是应用引擎如何连接到云sql实例的问题。
为什么会这样?怎么解决的?
我认为这是因为从 App Engine 应用程序到 Cloud SQL 的请求受制于以下时间和连接 limits:
- 对于 App Engine 标准环境中的应用 运行,所有数据库请求必须在 HTTP 请求计时器(大约 60 秒)内完成。对于灵活环境中的应用 运行,所有数据库请求必须在 60 分钟内完成。
- cron 任务等离线请求有 10 分钟的时间限制。
- 对云的请求 SQL 有限制,具体取决于 App Engine 模块的扩展类型以及实例可以在内存中保留(驻留)的时间。
- 标准环境中的每个 App Engine 实例 运行 与云 SQL 实例的并发连接不能超过 60 个。对于使用 Java 8 或 Go 1.8 编写的应用程序,限制为 100。
- Connection Issues: 如果您看到包含 "Aborted connection nnnn to db:" 的错误,这通常表示您的应用程序未正确终止连接。它也可能是由网络问题引起的。此错误并不意味着您的 Cloud SQL 实例存在问题。
您看到的 "Aborted connection" 消息通常是在连接未正确关闭或服务器与客户端之间存在网络异常时触发的。
有时 Cloud SQL 个实例和 GAE 有 long-live 个空闲连接。为了解决这个问题,建议将“wait_timeout”标志设置为低于 600 秒 - 正如您已经尝试过的那样。
另一种可能的解决方案是实施 application-level 保活。 SQLAlchemy 提供“pre-ping” for this. Otherwise, generate activity on all open connections by sending a simple SQL statement such as "SELECT 1;" regularly, at least once every 5 minutes. Also consider using statements in your code like “with db.connect() as conn:”来控制连接的生命周期。