简体   繁体   English

阻塞DBCP连接池(打开和关闭连接)。 OpenEJB中的数据库连接池是否可插入?

[英]Blocking on DBCP connection pool (open and close connection). Is database connection pooling in OpenEJB pluggable?

We use OpenEJB on Tomcat (used to run on JBoss, Weblogic, etc.). 我们在Tomcat上使用OpenEJB(用于在JBoss,Weblogic等上运行)。 While running load tests we experience significant performance problems with handling JMS messages (queues). 在运行负载测试时,我们在处理JMS消息(队列)时会遇到严重的性能问题。 Problem was localized to blocking on database connection pool getting or releasing connection to the pool. 问题仅限于阻止数据库连接池获取或释放与该池的连接。 Blocking prevented concurrent MDB instances (threads) from running hence performance suffered 10-fold and worse. 阻塞阻止并发MDB实例(线程)运行,因此性能遭受10倍甚至更糟的影响。 The same code used to run on application servers (with their respective connection pool implementations) with no blocking at all. 用于在应用程序服务器上运行相同的代码(及其各自的连接池实现),完全没有阻塞。

Example of thread blocked: 线程阻塞的示例:

Name: JMS Resource Adapter-worker-23
State: BLOCKED on org.apache.commons.pool.impl.GenericObjectPool@1ea6b4a owned by: JMS Resource Adapter-worker-19
Total blocked: 18,426  Total waited: 0

Stack trace: 
org.apache.commons.pool.impl.GenericObjectPool.returnObject(GenericObjectPool.java:916)
org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:91)
   - locked org.apache.commons.dbcp.PoolableConnection@1bcba8
org.apache.commons.dbcp.managed.ManagedConnection.close(ManagedConnection.java:147)
com.xxxxx.persistence.DbHelper.closeConnection(DbHelper.java:290)
....

Couple of questions. 几个问题。

  1. I am almost certain that some transactional attributes and properties contribute to this blocking, but MDBs are defined as non-transactional (we use both annotations and ejb-jar.xml). 我几乎可以肯定,某些​​事务属性和属性会导致这种阻塞,但是MDB被定义为非事务性的(我们同时使用了注释和ejb-jar.xml)。 Some EJBs do use container-managed transactions though (and we can observe blocking there as well). 但是,某些EJB确实使用容器管理的事务(并且我们也可以观察到那里的阻塞)。 Are there any DBCP configurations that may fix blocking? 是否有任何DBCP配置可以解决阻塞问题?
  2. Is DBCP connection pool implementation replaceable in OpenEJB? DBCP连接池实现可以在OpenEJB中替换吗? How easy (difficult) to replace it with another library? 用另一个库替换它有多容易(困难)?

Just in case this is how we define data source in OpenEJB (openejb.xml): 以防万一,这就是我们在OpenEJB(openejb.xml)中定义数据源的方式:

<Resource id="MyDataSource" type="DataSource">
  JdbcDriver oracle.jdbc.driver.OracleDriver
  JdbcUrl ${oracle.jdbc}
  UserName ${oracle.user}
  Password ${oracle.password}
  JtaManaged true
  InitialSize 5
  MaxActive 30
  ValidationQuery SELECT 1 FROM DUAL
  TestOnBorrow true
</Resource>

My 2 cts... 我的2克拉...

1 - Are there any DBCP configurations that may fix blocking? 1-是否有任何DBCP配置可以解决阻塞问题?

Although I cannot see it in the doc, I think there should also be a setting attribute named 'WhenExaustedAction' in the Resource node that could take a value "GROW" (value 2) as opposed to "BLOCK" (value 1) or "FAIL" (value 0). 尽管我在文档中看不到它,但我认为Resource节点中还应该有一个名为“ WhenExaustedAction”的设置属性,该属性可以采用值“ GROW”(值2),而不是“ BLOCK”(值1)或“ FAIL”(值0)。 This comes straight from the Pools common. 这直接来自Pools的常见问题。 Both Hibernate and Cayenne do use this DBCP setting. Hibernate和Cayenne均使用此DBCP设置。 Don't know about OpenEJB though. 虽然不了解OpenEJB。

No need to say that this would work only if all connections are dutifully closed of course (which is sometimes hard to guarantee). 不必说,仅当所有连接都已完好地关闭(有时很难保证)时,这才起作用。 Then you could probably see through JMX how many connections you need at peak activity time and you could then set the maxActive to a higher value evolved from these measures. 然后,您可能会通过JMX看到在高峰活动时间需要多少个连接,然后可以将maxActive设置为根据这些度量得出的更高值。

2 - Is DBCP connection pool implementation replaceable in OpenEJB? 2-DBCP连接池实现可以在OpenEJB中替换吗? How easy (difficult) to replace it with another library? 用另一个库替换它有多容易(困难)?

Sorry no idea. 不好意思 Would imagine yes. 可以想象是的。 Or possibly DBCP allows another connection pool manager. 也许DBCP允许另一个连接池管理器。

UPDATE: Just had a look in the code and it seems DBCP is the only option for connection pooling. 更新:只看了一下代码,似乎DBCP是连接池的唯一选择。

Incidentally I've seen that the whenExhaustedAction settings. 顺便说一句,我已经看到了whenExhaustedAction设置。 is not supported by openejb.xml. openejb.xml不支持。
There would however, still be one option left, since you are using an Oracle Database. 但是,由于您使用的是Oracle数据库,因此仍然只有一个选择。
One thing you could try is to use Oracle implicit connection caching (assuming version 10g) and leave DBCP with an arbitrary "sufficient" amount of connections. 您可以尝试的一件事是使用Oracle隐式连接缓存(假定版本为10g),并为DBCP保留任意数量的“足够”连接。 To do so, you would need to configure in the openejb.xml resource block, ConnectionProperties properties and use Oracle JDBC connection properties. 为此,您需要在openejb.xml资源块中配置ConnectionProperties属性,并使用Oracle JDBC连接属性。 That is connectionCachingEnabled=true and at least connectionCacheName and connectionCacheProperties . 那就是connectionCachingEnabled=true ,至少是connectionCacheNameconnectionCacheProperties In this way I would lure DBCP into believing it's doing the real job and actually using Oracle's pooling mechanism. 这样,我将诱使DBCP相信它正在完成真正的工作,并且实际上使用了Oracle的池化机制。 That would also mean taking little risks with DBCP and thereby a more liberal sizing of the maxActive setting. 这也意味着对DBCP承担很少的风险,从而可以更加自由地调整maxActive设置的大小。

Resolved issue with dbcp blocking by changing pool configuration ( openejb.xml ): 通过更改池配置( openejb.xml )解决了dbcp阻塞的问题:

TestOnBorrow false

Thank you, Andy , from OpenEJB team! 谢谢OpenEJB团队的Andy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM