0

Я настроил приложение Play 1.3 для использования четырех баз данных (на трех разных серверах).Как настроить пул соединений в Play Framework 1.3 через application.conf и c3p0.properties?

Существовал проблема связей утечки, эта проблема была частично решена, я писал об этом -

Do I need to annotate JPA actions with @Transactional in Play Framework-1.x to prevent the connection leak?

Теперь я настроить C3P0 пул соединений и хотел бы знать, как сделать это правильно.

Я создал c3p0.properties файл внутри conf.

c3p0.properties:

... 
c3p0.acquireIncrement=5 
c3p0.maxIdleTime=60 
c3p0.maxIdleTimeExcessConnections=10 
c3p0.maxPoolSize=200 
c3p0.minPoolSize=20 
c3p0.numHelperThreads=6 
c3p0.unreturnedConnectionTimeout=30 
... 

В файле application.conf я комментировал настройки пула соединений:

... 
# db.hardwareLayer.pool.timeout=10000 
# db.hardwareLayer.pool.maxSize=500 
# db.hardwareLayer.pool.minSize=100 

# db.applicationLayer.pool.timeout=10000 
# db.applicationLayer.pool.maxSize=500 
# db.applicationLayer.pool.minSize=100 

... 

etc 

Теперь я прочитал мои конфигурации (только для тестирования):

ComboPooledDataSource local = (ComboPooledDataSource) DB.datasource; 

Logger.info("MaxConnectionAge: " + 
    local.getMaxConnectionAge()); 
Logger.info("MaxPoolSize: " + 
    local.getMaxPoolSize()); 
Logger.info("NumConnectionsAllUsers: " + 
    local.getNumConnectionsAllUsers()); 
Logger.info("NumConnectionsDefaultUsers: " + 
    local.getNumConnectionsDefaultUser()); 
Logger.info("NumBusyConnectionsAllUsers: " + 
    local.getNumBusyConnectionsAllUsers()); 
Logger.info("NumBusyConnectionsDefaultUser: " + 
    local.getNumBusyConnectionsDefaultUser()); 
Logger.info("LastCheckinFailureDefaultUser: " + 
    local.getLastCheckinFailureDefaultUser()); 
Logger.info("NumFailedCheckinsDefaultUser: " + 
    local.getNumFailedCheckinsDefaultUser()); 
Logger.info("NumFailedCheckoutsDefaultUser: " + 
    local.getNumFailedCheckoutsDefaultUser()); 
Logger.info("NumIdleConnectionsAllUser: " + 
    local.getNumIdleConnectionsAllUsers()); 
Logger.info("NumIdleConnectionsDefaultUser: " + 
    local.getNumIdleConnectionsDefaultUser()); 
Logger.info("UnreturnedConnectionTimeout: " + 
    local.getUnreturnedConnectionTimeout()); 
Logger.info("NumUnclosedOrphanedConnectionsAllUsers: " + 
    local.getNumUnclosedOrphanedConnectionsAllUsers()); 
Logger.info("NumUnclosedOrphanedConnectionsDefaultUsers: " + 
local.getNumUnclosedOrphanedConnectionsDefaultUser()); 

Это дает:

20:10:04,432 INFO ~ MaxConnectionAge: 0 
20:10:04,432 INFO ~ MaxPoolSize: 30 
20:10:04,432 INFO ~ NumConnectionsAllUsers: 1 
20:10:04,432 INFO ~ NumConnectionsDefaultUsers: 1 
20:10:04,432 INFO ~ NumBusyConnectionsAllUsers: 1 
20:10:04,432 INFO ~ NumBusyConnectionsDefaultUser: 1 
20:10:04,432 INFO ~ LastCheckinFailureDefaultUser: null 
20:10:04,432 INFO ~ NumFailedCheckinsDefaultUser: 0 
20:10:04,432 INFO ~ NumFailedCheckoutsDefaultUser: 0 
20:10:04,432 INFO ~ NumIdleConnectionsAllUser: 0 
20:10:04,432 INFO ~ NumIdleConnectionsDefaultUser: 0 
20:10:04,432 INFO ~ UnreturnedConnectionTimeout: 30 
20:10:04,432 INFO ~ NumUnclosedOrphanedConnectionsAllUsers: 0 
20:10:04,432 INFO ~ NumUnclosedOrphanedConnectionsDefaultUsers: 0 

Почти все настройки по умолчанию, кроме unreturnedConnectionTimeout, которые я установил в файле c3p0.properties.

Настройки по умолчанию определены в исходном коде рамки -

Соответствующая часть DBConfig.java:

ComboPooledDataSource ds = new ComboPooledDataSource(); 
ds.setDriverClass(p.getProperty(propsPrefix+".driver")); 
ds.setJdbcUrl(p.getProperty(propsPrefix + ".url")); 
ds.setUser(p.getProperty(propsPrefix + ".user")); 
ds.setPassword(p.getProperty(propsPrefix + ".pass")); 
ds.setAcquireRetryAttempts(10); 
ds.setCheckoutTimeout(Integer.parseInt(p.getProperty(propsPrefix + ".pool.timeout", "5000"))); 
ds.setBreakAfterAcquireFailure(false); 
ds.setMaxPoolSize(Integer.parseInt(p.getProperty(propsPrefix + ".pool.maxSize", "30"))); 
ds.setMinPoolSize(Integer.parseInt(p.getProperty(propsPrefix + ".pool.minSize", "1"))); 
ds.setMaxIdleTimeExcessConnections(Integer.parseInt(p.getProperty(propsPrefix + ".pool.maxIdleTimeExcessConnections", "0"))); 
ds.setIdleConnectionTestPeriod(10); 
ds.setTestConnectionOnCheckin(true); 

Затем я проверяю пул соединений:

SELECT 
    dbExecConnections.session_id, 
    dbExecSessions.status, 
    /*client_net_address,*/ 
    program_name, 
    host_process_id, 
    login_name 

FROM 
    sys.dm_exec_connections dbExecConnections 
    JOIN sys.dm_exec_sessions dbExecSessions 
     ON dbExecConnections.session_id = dbExecSessions.session_id 

CROSS APPLY sys.dm_exec_sql_text(dbExecConnections.most_recent_sql_handle) AS dest 

enter image description here

Затем я делаю sma DDoS-атаки на мое приложение. Неудачи чередуется с нормальными работами приложений и через некоторое время система находится стабилизируется (из-за параметра unreturnedConnectionTimeout):

20:29:32,317 ERROR ~ An attempt by a client to checkout a Connection has timed o 
ut. 
20:29:32,363 ERROR ~ 
@6mebbn9f8 
Internal Server Error (500) for request POST /api/devices/kladr/levelthree 

Oops: PersistenceException 
An unexpected error occured caused by exception PersistenceException: org.hibern 
ate.exception.GenericJDBCException: Could not open connection 

play.exceptions.UnexpectedException: Unexpected Error 
     at play.Invoker$Invocation.onException(Invoker.java:244) 
     at play.Invoker$Invocation.run(Invoker.java:306) 
     ... 14 more 
20:29:39,520 DEBUG ~ select kladr0_.CODE as CODE1_0_, kladr0_.GNIMB as GNIMB2_0_ 
, kladr0_.[INDEX] as INDEX3_0_, kladr0_.NAME as NAME4_0_, kladr0_.OCATD as OCATD 
5_0_, kladr0_.SOCR as SOCR6_0_, kladr0_.Status as Status7_0_, kladr0_.UNO as UNO 
8_0_ from KLADR kladr0_ where kladr0_.CODE like '%63023_00____%' 
20:29:40,227 DEBUG ~ select kladr0_.CODE as CODE1_0_, kladr0_.GNIMB as GNIMB2_0_ 
, kladr0_.[INDEX] as INDEX3_0_, kladr0_.NAME as NAME4_0_, kladr0_.OCATD as OCATD 
5_0_, kladr0_.SOCR as SOCR6_0_, kladr0_.Status as Status7_0_, kladr0_.UNO as UNO 
8_0_ from KLADR kladr0_ where kladr0_.CODE like '%63024_00____%' 
20:29:45,900 WARN ~ SQL Error: 0, SQLState: null 
20:29:45,900 ERROR ~ An attempt by a client to checkout a Connection has timed o 
ut. 
20:29:45,932 ERROR ~ 
@6mebbn9fa 
Internal Server Error (500) for request POST /api/devices/kladr/levelthree 

Oops: PersistenceException 
An unexpected error occured caused by exception PersistenceException: org.hibern 
ate.exception.GenericJDBCException: Could not open connection 
play.exceptions.UnexpectedException: Unexpected Error 
     at play.Invoker$Invocation.onException(Invoker.java:244) 
     ... 14 more 
20:29:46,236 DEBUG ~ select kladr0_.CODE as CODE1_0_, kladr0_.GNIMB as GNIMB2_0_ 
, kladr0_.[INDEX] as INDEX3_0_, kladr0_.NAME as NAME4_0_, kladr0_.OCATD as OCATD 
5_0_, kladr0_.SOCR as SOCR6_0_, kladr0_.Status as Status7_0_, kladr0_.UNO as UNO 
8_0_ from KLADR kladr0_ where kladr0_.CODE like '%63026_00____%' 
20:29:52,873 DEBUG ~ select kladr0_.CODE as CODE1_0_, kladr0_.GNIMB as GNIMB2_0_ 
, kladr0_.[INDEX] as INDEX3_0_, kladr0_.NAME as NAME4_0_, kladr0_.OCATD as OCATD 
5_0_, kladr0_.SOCR as SOCR6_0_, kladr0_.Status as Status7_0_, kladr0_.UNO as UNO 
8_0_ from KLADR kladr0_ where kladr0_.CODE like '%63027_00____%' 
20:29:53,491 DEBUG ~ select kladr0_.CODE as CODE1_0_, kladr0_.GNIMB as GNIMB2_0_ 
, kladr0_.[INDEX] as INDEX3_0_, kladr0_.NAME as NAME4_0_, kladr0_.OCATD as OCATD 
5_0_, kladr0_.SOCR as SOCR6_0_, kladr0_.Status as Status7_0_, kladr0_.UNO as UNO 
8_0_ from KLADR kladr0_ where kladr0_.CODE like '%63028_00____%' 
20:29:54,090 DEBUG ~ select kladr0_.CODE as CODE1_0_, kladr0_.GNIMB as GNIMB2_0_ 
, kladr0_.[INDEX] as INDEX3_0_, kladr0_.NAME as NAME4_0_, kladr0_.OCATD as OCATD   

Все это хорошо.

Но как собрать все необходимые конфигурации в одном файле? Если я раскомментировать настройки пула в application.conf:

20:32:44,908 INFO ~ MaxConnectionAge: 0 
20:32:44,908 INFO ~ MaxPoolSize: 500 
20:32:44,909 INFO ~ NumConnectionsAllUsers: 100 
20:32:44,909 INFO ~ NumConnectionsDefaultUsers: 100 
20:32:44,910 INFO ~ NumBusyConnectionsAllUsers: 15 
20:32:44,910 INFO ~ NumBusyConnectionsDefaultUser: 15 
20:32:44,910 INFO ~ LastCheckinFailureDefaultUser: null 
20:32:44,910 INFO ~ NumFailedCheckinsDefaultUser: 0 
20:32:44,910 INFO ~ NumFailedCheckoutsDefaultUser: 0 
20:32:44,910 INFO ~ NumIdleConnectionsAllUser: 85 
20:32:44,910 INFO ~ NumIdleConnectionsDefaultUser: 85 
20:32:44,910 INFO ~ UnreturnedConnectionTimeout: 30 
20:32:44,910 INFO ~ NumUnclosedOrphanedConnectionsAllUsers: 0 
20:32:44,910 INFO ~ NumUnclosedOrphanedConnectionsDefaultUsers: 0 

Некоторые параметры считываются из application.conf, некоторые из c3p0.properties.

Я был бы очень признателен за информацию. Спасибо всем.

ответ

2

Play 1.x поддерживает только настройку подмножества опций c3p0 через application.conf. Если вы хотите не устанавливать значения по умолчанию для других пользователей, вам придется поддерживать файл c3p0.properties.

Благодаря C3P0 в Precedence of Configuration Settings и тот факт, что Play программно задает свойства, которые могут быть сконфигурированы с application.conf - вы не можете использовать файл c3p0.properties установить Play поддерживаются параметры.

Так что для конфигурации, которую вы пытаетесь реализовать, вам необходимо будет поддерживать параметры конфигурации источника данных в обоих файлах (или fork Play, чтобы получить то, что вы хотите).

+0

Спасибо за ваш ответ! –