JDBC连接池与App Engine兼容

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

我正在使用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.(Thread.java:527) at com.zaxxer.hikari.util.DefaultThreadFactory.newThread(DefaultThreadFactory.java:32) at java.util.concurrent.ThreadPoolExecutor$Worker.(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.(HikariPool.java:161) at com.zaxxer.hikari.pool.HikariPool.(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.(Thread.java:448) at org.vibur.objectpool.reducer.SamplingPoolReducer.(SamplingPoolReducer.java:78) at org.vibur.dbcp.pool.PoolOperations$PoolReducer.(PoolOperations.java:88) at org.vibur.dbcp.pool.PoolOperations$PoolReducer.(PoolOperations.java:86) at org.vibur.dbcp.pool.PoolOperations.(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.(Thread.java:487) ... 

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

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

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

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

…如果创建新连接的时间与测试现有连接是否处于活动状态并重新使用它的时间大致相同,那么我们建议您创建一个新连接来为每个HTTP请求提供服务,并在其持续时间内重复使用它。请求。 特别是,当您从Google App Engine连接到Google Cloud SQL时,后一种情况可能适用。

您可能会收到AccessControlException,因为您的应用程序设置为“自动缩放”。

过去,GAE应用程序可能是“后端”或“前端”,只有后端才能使用后台线程。 现在,后端被弃用并替换为模块,后台线程的使用与应用程序的扩展类型相关联。

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