如何通过application.conf和c3p0.properties在Play Framework 1.3中配置连接池?
How to configure the connection pool in Play Framework 1.3 through application.conf and c3p0.properties?
我将 Play 1.3 应用程序配置为使用四个数据库(在三个不同的服务器上)。
出现了漏接的问题,这个问题已经部分解决了,我写过这个-
Do I need to annotate JPA actions with @Transactional in Play Framework-1.x to prevent the connection leak?
现在我配置c3p0连接池,想知道如何正确配置。
我在 conf
目录中创建了 c3p0.properties
文件。
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
然后我对我的应用程序进行小型 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。
Play 1.x 仅支持通过 application.conf 配置 c3p0 选项的子集。如果你想要任何其他人的非默认值,那么你将不得不维护一个 c3p0.properties 文件。
由于 c3p0 的 Precedence of Configuration Settings 以及 Play 以编程方式设置属性 可以 配置为 application.conf - 你不能使用 c3p0.properties 文件来设置播放支持的选项。
因此 - 对于您尝试实施的配置,您将需要在两个文件中维护数据源配置设置(或 fork Play 以获得您想要的内容)。
我将 Play 1.3 应用程序配置为使用四个数据库(在三个不同的服务器上)。
出现了漏接的问题,这个问题已经部分解决了,我写过这个-
Do I need to annotate JPA actions with @Transactional in Play Framework-1.x to prevent the connection leak?
现在我配置c3p0连接池,想知道如何正确配置。
我在 conf
目录中创建了 c3p0.properties
文件。
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
然后我对我的应用程序进行小型 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。
Play 1.x 仅支持通过 application.conf 配置 c3p0 选项的子集。如果你想要任何其他人的非默认值,那么你将不得不维护一个 c3p0.properties 文件。
由于 c3p0 的 Precedence of Configuration Settings 以及 Play 以编程方式设置属性 可以 配置为 application.conf - 你不能使用 c3p0.properties 文件来设置播放支持的选项。
因此 - 对于您尝试实施的配置,您将需要在两个文件中维护数据源配置设置(或 fork Play 以获得您想要的内容)。