9

Uwaga: Wiem o wątku this, ale jest dość stary, a ponadto rozwiązanie nie działa dla mnie.Pula połączeń JDBC zgodna z App Engine

Używam App Engine razem z Cloud SQL i chciałbym udostępnić pulę otwartych połączeń między wszystkimi obecnymi użytkownikami aplikacji. Próbowałem kilku implementacji pul połączeń i wszystkie one działają doskonale z lokalnym serwerem programistycznym, jednak po wdrożeniu w chmurze zawodzą. Przypuszczam, że powodem jest ograniczone środowisko "piaskownicy" App Engine. Czy ktoś wie o puli połączeń JDBC działającej w App Engine?

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) 
... 

Connection Tomcat JDBC Basen

... 
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) 
... 
+0

widziany na jakichś innych pytań stackoverflow że HikariCP wspiera niestandardowe ThreadManager, dzięki czemu można tworzyć wątki za pomocą białej listy ThreadManager GAE za. –

Odpowiedz

2

Prawdopodobnie nie trzeba w ogóle połączenie pooling:

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

... jeśli czas Utwórz nowe połączenie dotyczy tak samo jak testowanie, czy istniejące połączenie jest aktywne i ponowne używanie go, zalecamy utworzenie nowego połączenia w celu obsługi każdego żądania HTTP i ponowne użycie go na czas trwania żądania. W szczególności ten drugi przypadek może mieć zastosowanie , gdy łączysz się z Google App Engine z Google Cloud SQL.

+1

Tak, wiem o tym. Jednak każda instancja App Engine nie może mieć więcej niż 12 równoczesnych połączeń z instancją Cloud SQL i jest to kolejny powód, aby mieć pulę połączeń, ponieważ śledzi ona aktywne połączenia, a jeśli nie ma żadnej dostępnej, blokuje do czasu, gdy jedna będzie dostępna lub czasowa. na zewnątrz. W przeciwnym razie skończyłbym z błędem. – pgiecek

+2

Z tego co wiem, Java GAE domyślnie wysyła tylko 10 równoczesnych żądań do twojej instancji, więc 12 równoczesnych połączeń db powinno być w porządku. – Christiaan

+0

Możliwym problemem jest to, że Google ma dzienny limit połączeń z gniazdem, z których może korzystać aplikacja. Bez łączenia łatwiejsze będzie osiągnięcie tego limitu i nagle Twoja aplikacja nie może połączyć się z bazą danych. Limit jest bardzo wysoki, więc możesz go nigdy nie trafić, ale jeśli to zrobisz, efekty są zauważalne. – depsypher

3

Musiałem użyć Tomcat DBCP 1.4 (starsza wersja), ponieważ frontend GAE nie pozwala wątkom na życie poza zakresem żądania. Oto przykładowy projekt: https://github.com/kennberg/appengine-java-connection-pool

Pamiętaj, że pula połączeń jest niezbędna, gdy masz zbyt wiele żądań, ponieważ istnieje limit liczby oczekujących połączeń na wystąpienie. Ponowne używanie połączeń pomaga utrzymać się poniżej limitu.

+0

Yip, każda instancja GAE ma limit 12 połączeń. Wydaje się bardzo niska .. – cfl

+0

Dzięki Alex, używałem wersji 2.x i po prostu nie mogę określić, co jest przyczyną. Zmniejszono go do wersji 1.4 i działał jak czar. – Jay

0

Może pojawić się wyjątek AccessControlException, ponieważ aplikacja jest ustawiona na "Automatyczne skalowanie".

Kiedyś aplikacja GAE mogła być "zapleczem" lub "frontendem" i tylko backendy mogły używać wątków w tle. Teraz, gdy wycofania są wycofywane i zastępowane modułami, użycie wątków w tle jest powiązane z typem skalowania aplikacji.

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