使用Cloud SQL的应用引擎上的连接池

时间:2014-01-30 13:22:39

标签: java google-app-engine google-cloud-sql

听起来,应用引擎(1)的较新的云SQL JDBC驱动程序支持连接池。

我们的应用程序使用Spring + Hibernate,我们正在尝试使用现有的java框架之一进行连接池(BoneCP,C3p0,Hikari),并且由于应用程序引擎的限制,目前已失败使用它们中的任何一个。使用下面的Spring + Hibernate + C3p0进行堆栈跟踪。有没有人设法让这个工作?

[INFO] java.lang.NoClassDefFoundError: java.lang.management.ManagementFactory is a restricted class. Please see the Google  App Engine developer's guide for more details.
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51)
[INFO]  at com.mchange.v2.c3p0.management.ActiveManagementCoordinator.<init>(ActiveManagementCoordinator.java:54)
[INFO]  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[INFO]  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
[INFO]  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[INFO]  at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance_(Runtime.java:127)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance(Runtime.java:148)
[INFO]  at com.mchange.v2.c3p0.C3P0Registry.<clinit>(C3P0Registry.java:146)
[INFO]  at java.lang.Class.forName0(Native Method)
[INFO]  at java.lang.Class.forName(Class.java:190)
[INFO]  at com.google.appengine.tools.development.agent.runtime.RuntimeHelper.checkRestricted(RuntimeHelper.java:70)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.checkRestricted(Runtime.java:64)
[INFO]  at com.mchange.v2.c3p0.impl.DriverManagerDataSourceBase.<init>(DriverManagerDataSourceBase.java:212)
[INFO]  at com.mchange.v2.c3p0.DriverManagerDataSource.<init>(DriverManagerDataSource.java:72)
....

(1):旧驱动程序= com.google.appengine.api.rdbms.AppEngineDriver。新驱动程序= com.mysql.jdbc.GoogleDriver。

3 个答案:

答案 0 :(得分:3)

我们最终通过使用Tomcat DBCP(http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html)解决了这个问题。大多数其他池的问题在于它们使用线程,应用引擎的模型阻止前端实例(长期存在的线程)。

答案 1 :(得分:2)

这是一个老问题,但我想提供我认为更准确的答案。通过使用他们的 ThreadFactory,Google App Engine allow applications to create threads

HikariCP允许配置外部ThreadFactory

所以,配置会是这样的:

import com.google.appengine.api.ThreadManager;
...

HikariConfig config = new HikariConfig();
config.setThreadFactory(ThreadManager.backgroundThreadFactory());
...

更新:解决以下关于前端实例的评论......为noted elsewhere

"Keep in mind that instances are created and destroyed dynamically, and requests are routed
to instances based purely on availability. ... There is no guarantee that requests of a
particular sort will always be handled by the same instance, nor is it assured that an
instance will still be around after a given request is handled. Outside of a request
handler, the application is not given the opportunity to rescue data from local memory
prior to an instance being shut down."

这大大降低了前端连接池的实用性。事实上,如果数据库不在内存中,这是一个坏主意,因为它可以创建大量的连接流失。对于本地内存数据库,它们不仅在GAE环境中易碎,而且在连接开销方面也很脆弱。很少是一个可以保证使用池的可扩展性因素。

答案 2 :(得分:2)

我使用Tomcat DBCP 1.4为GAE前端实例创建了一个示例,它不允许线程在请求​​范围之外生存。这适用于Java 7。

https://github.com/kennberg/appengine-java-connection-pool