App Engine Java Servlet 未连接到 Cloud SQL

Posted

技术标签:

【中文标题】App Engine Java Servlet 未连接到 Cloud SQL【英文标题】:App Engine Java Servlet does not connect to Cloud SQL 【发布时间】:2014-01-20 16:26:57 【问题描述】:

我使用应用引擎创建了一个 java web servlet,servlet 向数据库发出请求。我已经使用本地数据库在本地测试了 servlet,它运行良好,然后我继续在本地测试 servlet,但我访问了 Cloud SQL 数据库,这也很完美。

我的问题是在我部署 servlet 后出现的。部署后,所有数据库请求都会返回以下内容:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not 
received any packets from the server.

我在云控制台中进行了检查,我的应用已正确添加到访问控制选项卡下的云 SQL 授权 App Engine 应用程序中。

有人在部署应用引擎 servlet 时遇到过类似问题吗?有什么解决方案或建议吗?我将不胜感激任何和所有的帮助!!!

更新:

上述错误是使用以下代码访问db产生的

Class.forName("com.mysql.jdbc.Driver");
Url = "jdbc:mysql://<ip-address-cloudsql>:3306/<dbname>";
Connection con = DriverManager.getConnection (Url,"root",<password>);

使用此代码也遇到了相同的错误,请注意它与此处示例中显示的代码非常相似 https://developers.google.com/appengine/docs/java/cloud-sql/

Class.forName("com.mysql.jdbc.GoogleDriver");
Url = "jdbc:google:mysql://<appID:instanceID>/<dbname>? 
user=root&password=<password>";
Connection con = DriverManager.getConnection (Url);

在使用 appid 和实例 id 设置 url 时,我遵循了此 *** 帖子中显示的格式提示: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:

使用此代码会导致以下不同的错误:

java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)

我假设它说的是 localhost,因为我的 cloudsql 数据库设置为遵循应用程序引擎 servlet。另外,要知道这两种方法在本地运行 servlet 和访问云 sql 数据库时都可以正常工作。

有什么想法吗?我不知道还能尝试什么:[

【问题讨论】:

您是否更改了root@localhost 的密码?默认情况下,root@localhost 没有密码。有助于查看用户/密码状态的查询是 SELECT user,host,password FROM mysql.user 我以为我在云控制台中更改了它。但是在运行该查询时,只为 % 用户设置了密码,localhost 是空白的。修改密码为空成功,谢谢!但是我也想为本地主机添加密码,我该怎么做? 您应该能够使用如下查询设置 root@localst 密码:UPDATE mysql.user SET password = PASSWORD('XXXX') WHERE user = 'root' AND host = 'localhost' 其中XXXX 是您想要的密码。 还有一件事:不要忘记在更改 mysql.user 表后执行FLUSH PRIVILEGES。否则 mysqld 将不会接受更改。 【参考方案1】:

从授权的 App Engine 应用程序连接到 Cloud SQL 时,不需要密码(实际上如果您尝试使用密码连接会失败)。

将您的连接字符串更改为 jdbc:google:mysql://<appID:instanceID>/<dbname>? user=root 省略 &amp;password=&lt;password&gt; 部分

【讨论】:

哇,这节省了我几个小时。尝试使用密码时的错误消息并不完全有用。 是的,它浪费了很多时间试图弄清楚为什么它不起作用。确实不是一条有用的消息 只花了 2 个小时在这个 :( 他们本可以在他们的文档中强调这一点...... 我遇到了类似的错误,但在删除密码后它开始给出错误“无密码”。网址现在也已更改(jdbc:google:mysql://$INSTANCE_CONNECTION_NAME/$database‌​?user=$user&pa‌​ssword=$password)请参考cloud.google.com/appengine/docs/standard/java/cloud-sql/… 您能否进一步说明 appID 和 instanceID 应该是什么?【参考方案2】:

如果您有授权的 App Engine 应用程序,您的应用程序引擎在访问控制设置上不需要密码,因为它是本地的,所以只需让您密码 = "";但是,如果您使用远程设备,例如从另一台主机、命令行或 GCE VM 运行的远程设备,通过 TCP、SSH 或 html 运行,您将需要密码 =“something”;您在访问控制中设置的内容。

【讨论】:

【参考方案3】:

致所有来自 Google 的人,他们正在寻找您为什么会在连接上收到“com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure”。

如果您从测试服务器调用,请确保您的 IP 是允许的。

我在朋友家测试,这个无益的错误不断出现。

【讨论】:

【参考方案4】:

连接到 Google Cloud Sql 时,您应该小心: - 关闭你打开的连接 -尝试创建新连接时使用指数退避算法。 更多信息请见:https://cloud.google.com/sql/faq

【讨论】:

【参考方案5】:

如果您在 Spring Boot 应用程序中使用 application.properties,则只需将以下行放入 application.properties

spring.datasource.url: jdbc:mysql://google/<dbname>?cloudSqlInstance=<InstanceName>&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=****&password=****

【讨论】:

这是用于本地 mysql 服务器而不是用于云 App Engine 上的应用程序。

以上是关于App Engine Java Servlet 未连接到 Cloud SQL的主要内容,如果未能解决你的问题,请参考以下文章

Google App Engine Java HTTP Post 图像从 API 方法到 Servlet

有哪些库可以在 Google App Engine/Java Servlet 上处理 XML

google app engine java - 基于域的重定向

gwt- 如何读取文本文件(Google App Engine servlet)?

如何将过滤器与 Google App Engine 的 app.yaml 中的 servlet 相关联?

如何在 Google App Engine 的 app.yaml 文件中配置 servlet 过滤器?