Google App Engine 和 Cloud SQL:在“读取初始通信数据包”时失去与 MySQL 服务器的连接

Posted

技术标签:

【中文标题】Google App Engine 和 Cloud SQL:在“读取初始通信数据包”时失去与 MySQL 服务器的连接【英文标题】:Google App Engine and Cloud SQL: Lost connection to MySQL server at 'reading initial communication packet' 【发布时间】:2014-09-28 03:31:02 【问题描述】:

我在 Google App Engine 应用上有一个 Django 应用,它使用 App Engine authentication 连接到 Google Cloud SQL。

大多数情况下一切正常,但有时会引发以下异常:

OperationalError: (2013, "Lost connection to mysql server at 'reading initial communication packet', system error: 38")

根据the docs,在以下情况下会返回此错误:

如果 Google Cloud SQL 拒绝连接,例如,因为您的客户端连接的 IP 地址未经授权。

这对我来说没有多大意义,因为身份验证是由 App Engine 服务器完成的。

什么可能导致这些零星错误?

【问题讨论】:

只是为了确保您的应用程序已部署到云端,对吗?你没有运行 localhost? @Gwell 是的,它在 GAE 云上。 我无法准确找到关于错误 38 的太多信息。但大多数关于在“读取初始命令..等”时丢失与 MySQL 服务器的连接的错误都与 SQL 设置有关,尤其是超时和授权,但这些都是本地主机问题。查看此文档:developers.google.com/cloud-sql/docs/admin-api/v1beta1/… 并查看您是否可以在 Cloud SQL 实例上修改任何可以解决此问题的设置。 您是否将应用设置为仅在欧盟服务器上运行? 我时常遇到同样的问题。我使用 CloudSQL 在 AppEngine 上运行 Django 1.5,偶尔会遇到同样的错误。 【参考方案1】:

我遇到了类似的问题,最后联系了 Google 寻求帮助。他们解释说,当他们需要重新启动或移动实例时会发生这种情况。如果客户端实例重新启动或移动到另一个主机服务器(对于各种版本),IP 将不匹配并抛出该错误。他们提到服务器可能会因补丁、错误和减速而重新启动,从而导致类似的行为(无论是相同的错误还是类似的错误)。服务器也会移动以尝试靠近实例以增加响应时间。如果您在移动期间发送请求,则会引发错误。

他们告诉我,如果发生这种情况,我需要在重试捕获中编写代码,类似于处理数据存储超时的方式。请记住内置回退机制,在重启后过快发送太多请求可能会导致崩溃。

这种情况多久发生一次?

【讨论】:

developers.google.com/cloud-sql/faq#maintenancerestartdevelopers.google.com/appengine/articles/…en.wikipedia.org/wiki/Exponential_backoff 谢谢,很高兴听到 Google 的回复。实际上,我们的代码中确实有重试,并且也有指数退避,但重试可能太少了..您的代码重试了多少次以及采用什么退避?重试是否完全解决了问题? 对我来说,如果仍然失败,我做了 3 次退休,我将它发送到任务队列。您可以更高,具体取决于您是否达到了实例的全局超时。我的任务队列很少见,但我见过一两次。你等了多长时间?它是否会在一个月内发生超过几次? 每月发生两次以上。5 次重试,5 秒延迟和 x2 回退。这是一个基本的扩展实例,所以没有全局超时。 刚发现有一些库代码没有用重试包装。我正在添加重试,让我们拭目以待,看看是否能解决问题。【参考方案2】:

在我们的例子中,我们在代码中错误地重命名了实例。当我们改回正确的名称时,一切正常。确保您的 Cloud SQL 实例在 Google Cloud Console 和用于访问它的代码中都正确命名,并确保您的 Cloud SQL 实例允许您的 Google App Engine 实例连接到它,它是 Access control

【讨论】:

这与原始问题无关。 99% 的时间它工作得很好【参考方案3】:

在我的情况下,问题是导致 CloudSQL 实例上的服务器 SSL 证书过期。奇怪的是,它没有显示在 Google Cloud Console 中,而是在下载证书并使用 openssl (openssl x509 -in server-ca.pem -text -noout) 解码后才发现。

在尝试连接 cloud_sql_proxy 后,我能够找出问题的原因;幸运的是,它给出了更有意义的错误消息couldn't connect to "...": x509: certificate has expired or is not yet valid

从 Google Cloud Console 重置 SSL 配置后,来自 AppEngine Standard 应用程序的连接立即开始工作。我注意到控制台上出现重置有效期后。

【讨论】:

尽管下载的证书仍然有效,但重置 SSL 对我有帮助【参考方案4】:

我在使用 Django 1.10 和 GAE 时也遇到了这个问题。该应用程序在本地运行良好(通过 cloud_sql_proxy 连接云 sql),但在使用应用程序的 GAE 实例时我会收到 38 错误。

我的问题原来是我的数据库用户。用户中有一个连字符。一旦我创建了一个不带连字符的新用户并将我的应用程序更改为使用新用户,那么应用程序的 GAE 实例就会工作

【讨论】:

这与原始问题无关。 99% 的时间它工作得很好

以上是关于Google App Engine 和 Cloud SQL:在“读取初始通信数据包”时失去与 MySQL 服务器的连接的主要内容,如果未能解决你的问题,请参考以下文章

Google Cloud Tasks 和 Google App Engine Python 3

使用 Google App Engine 和 Google Cloud SQL 扩展 WordPress

Google App Engine - 大查询 - Python 找不到库 google.cloud

如何在 Google Cloud App Engine 上使用 PubSub 创建订阅者,该订阅者通过 Publisher 从 Google Cloud App Engine Flex 收听消息?

Google Cloud SDK 和 App Engine SDK 有啥区别

Google Cloud App Engine 文件存储备份