JDBC连接池与App Engine兼容

时间:2014-11-10 10:02:41

标签: java google-app-engine jdbc connection-pooling google-cloud-sql

注意:我知道this线程,但它已经很老了,而且解决方案对我不起作用。

我正在使用App Engine和Cloud SQL,我希望在所有应用程序的当前用户之间共享一个开放连接池。我已经尝试了几个连接池实现,它们都与本地开发服务器完美配合,但是,当部署到云时,它们会失败。我想原因是App Engine的限制"沙盒"环境。有没有人知道在App Engine上工作的JDBC连接池?

Apache Commons DBCP

...
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.commons.dbcp2.PoolableConnection
at com.google.appengine.runtime.Request.process-a49d46300800d0ca(Request.java)
at org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:254)
at org.apache.commons.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:2162)
at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2148)
at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:1903)
at org.apache.commons.dbcp2.BasicDataSource$PaGetConnection.run(BasicDataSource.java:2267)
at org.apache.commons.dbcp2.BasicDataSource$PaGetConnection.run(BasicDataSource.java:2263)
at java.security.AccessController.doPrivileged(AccessController.java:63)
at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1404)
...

Tomcat JDBC连接池

...
Caused by: java.lang.SecurityException: Unable to get members for class org.apache.tomcat.jdbc.pool.DataSource

...

Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
... 45 more
Caused by: java.lang.NoClassDefFoundError: javax/management/MalformedObjectNameException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2517)
... 45 more
Caused by: java.lang.ClassNotFoundException: javax.management.MalformedObjectNameException
... 45 more

HikariCP

...
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
at java.security.AccessController.checkPermission(AccessController.java:565)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:315)
at java.lang.Thread.init(Thread.java:378)
at java.lang.Thread.<init>(Thread.java:527)
at com.zaxxer.hikari.util.DefaultThreadFactory.newThread(DefaultThreadFactory.java:32)
at java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor.java:591)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:922)
at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1591)
at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:305)
at java.util.concurrent.ScheduledThreadPoolExecutor.scheduleAtFixedRate(ScheduledThreadPoolExecutor.java:542)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:161)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:114)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:102)
...

Vibur DBCP

...
Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
at java.security.AccessController.checkPermission(AccessController.java:565)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:315)
at java.lang.Thread.init(Thread.java:378)
at java.lang.Thread.<init>(Thread.java:448)
at org.vibur.objectpool.reducer.SamplingPoolReducer.<init>(SamplingPoolReducer.java:78)
at org.vibur.dbcp.pool.PoolOperations$PoolReducer.<init>(PoolOperations.java:88)
at org.vibur.dbcp.pool.PoolOperations$PoolReducer.<init>(PoolOperations.java:86)
at org.vibur.dbcp.pool.PoolOperations.<init>(PoolOperations.java:79)
at org.vibur.dbcp.ViburDBCPDataSource.start(ViburDBCPDataSource.java:197)
....

C3P0

...
Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
at java.security.AccessController.checkPermission(AccessController.java:565)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:315)
at java.lang.Thread.init(Thread.java:378)
at java.lang.Thread.<init>(Thread.java:487)
...

3 个答案:

答案 0 :(得分:3)

我不得不使用Tomcat DBCP 1.4(旧版本),因为GAE前端不允许线程在请求​​范围之外生存。这是一个示例项目: https://github.com/kennberg/appengine-java-connection-pool

请注意,一旦请求过多,连接池就是必需的,因为每个实例的挂起连接数有限制。重新使用连接有助于保持在极限之下。

答案 1 :(得分:2)

您可能根本不需要连接池:

https://cloud.google.com/sql/faq#connections

  

...如果创建新连接的时间与测试if的时间大致相同   现有的连接是活着的并且重用它,那么我们建议这样做   您创建一个新连接来为每个HTTP请求提供服务,并重用它   在请求期间。特别是后一种情况   从Google App Engine连接到Google Cloud SQL时适用。

答案 2 :(得分:0)

您可能会收到AccessControlException,因为您的应用程序设置为&#34; Automatic Sc​​aling&#34;。

过去,GAE应用程序可能是&#34;后端&#34;或者&#34;前端&#34;并且只有后端可以使用后台线程。现在不推荐使用后端并替换为模块,后台线程的使用与应用程序的扩展类型相关联。

https://cloud.google.com/appengine/docs/java/modules/#Java_Background_threads