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

12 投票
4 回答
8558 浏览
提问于 2025-04-18 16:04

我在Google App Engine上有一个Django应用,它连接到了Google Cloud SQL,使用的是App Engine的认证方式

大部分时间一切都运行得很好,但偶尔会出现以下错误:

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

根据文档,这个错误通常是在以下情况下出现:

如果Google Cloud SQL拒绝了连接,比如说你连接的客户端的IP地址没有被授权。

在我的情况下,这个说法不太合理,因为认证是由App Engine服务器来完成的。

那么,是什么原因导致这些偶尔出现的错误呢?

4 个回答

-1

我也遇到过这个问题,使用的是Django 1.10和GAE(Google App Engine)。在本地运行的时候,一切都很好(通过cloud_sql_proxy连接云数据库),但是在使用GAE实例时却出现了38错误。

我的问题其实是出在数据库用户上。那个用户的名字里有一个连字符(-)。当我创建了一个没有连字符的新用户,并把我的应用改成使用这个新用户后,GAE实例就正常工作了。

1

在我的情况下,问题是因为CloudSQL实例上的服务器SSL证书过期了。奇怪的是,这个过期的证书在Google Cloud控制台上没有显示出来,我是下载了证书并用openssl解码后才发现的(openssl x509 -in server-ca.pem -text -noout)。

我在尝试用cloud_sql_proxy连接时找到了问题的原因;幸运的是,它给出了更有意义的错误信息:无法连接到“...”:x509:证书已过期或尚未生效

在Google Cloud控制台重置SSL配置后,来自AppEngine标准应用的连接立刻就能正常工作了。我注意到重置后,控制台上出现了有效日期。

3

在我们的例子中,我们在代码里把实例的名字改错了。当我们把名字改回正确的,所有东西就都正常了。确保你的Cloud SQL实例在Google Cloud控制台和你用来访问它的代码里名字都正确,并且要确保你的Cloud SQL实例允许你的Google App Engine实例连接到它,这个设置在访问控制里。

16

我之前也遇到过类似的问题,最后联系了谷歌寻求帮助。他们解释说,这种情况发生在需要重启或移动一个实例的时候。如果客户端的实例被重启了,或者被移动到另一个主机服务器上(因为不同的版本),那么IP地址就会不匹配,从而出现错误。他们提到,服务器可能会因为更新补丁、出现错误或者变慢而重启,这样也会导致类似的情况(可能是同样的错误或类似的错误)。服务器还会移动,以便更靠近实例,从而提高响应速度。如果你在移动过程中发送请求,就会出现错误。

他们告诉我,我需要在代码中加入重试机制,以防这种情况发生,这和处理数据存储超时的方式类似。同时要注意设置退避机制,重启后如果发送请求太快,可能会导致崩溃。

这种情况发生的频率有多高呢?

撰写回答