【问题标题】:Modifying a JNDI connection pool programmaticaly以编程方式修改 JNDI 连接池
【发布时间】:2022-01-18 12:07:55
【问题描述】:

我在我的项目中使用 Apache Tomcat JDBC 连接池库并相应地配置了 context.xml 文件。我的应用程序实例需要在多个位置运行,但应用程序上的负载会有所不同,因此我想在运行时根据特定实例的客户大小修改 maxActive 大小和其他一些属性。

  <Context path="/abc"
             docBase="abc"
             debug="5"
             reloadable="false"
             crossContext="true">
       <Resource name="jdbc/abc"
          auth="Container"
          type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
          driverClassName="xxxxx"
          url="xxxxxxx"
          username="xxxxx" password="xxxxxx"
          maxActive="20"
          initialSize="0"
          ...
          />
     </Context>

【问题讨论】:

  • 您确定您使用的是 Tomcat JDBC 吗?在不使用factory 属性的情况下,Tomcat 的默认设置是使用重新打包的 DBCP2 版本。
  • 谢谢。打字时错过了工厂。
  • "multiple locations" -- 你是说客户端在多台机器上,而 MySQL 在一台服务器上?有多少?
  • @RickJames no Mysql 也在同一台服务器上。每个应用程序实例都有自己的数据库。

标签: java mysql tomcat jdbc connection-pooling


【解决方案1】:

您可以尝试为此使用标准 JMX。

正如您在documentation 中所见,Tomcat 可以将连接池公开为MBean object,您可以使用 JConsole 等工具与之交互。

the MBean implementation 基本上代表实际的org.apache.tomcat.jdbc.pool.ConnectionPool 可以通过 MBean 接口执行的不同操作,AFAIK,ConnectionPool 根据当前配置动态allocates connections


基于配置而非运行时行为的原始答案

请考虑查看this related SO questionself provided answer,我认为这可能会有所帮助。

Tomcat 在其configuration files 中替换系统提供的环境变量:

Tomcat 配置文件被格式化为无模式 XML;元素和 属性区分大小写。 Apache Ant 风格的变量替换是 支持的;名称为 propname 的系统属性可用于 使用语法 ${propname} 的配置文件。所有系统属性都是 可用,包括使用-D 语法设置的那些,那些自动 由 JVM 和在 $CATALINA_BASE/conf/catalina.properties 文件。

如前所述,包含需要由 Tomcat 动态替换的属性的最佳方法是使用 -D 选项将它们作为系统属性传递,并且可能在 JAVA_OPTS 环境变量中。

如上述问题所示,并在catalina.sh 中提供建议:

# Environment Variable Prerequisites
#
#   Do not set the variables in this script. Instead put them into a script
#   setenv.sh in CATALINA_BASE/bin to keep your customizations separate.
#

例如,在位于$CATALINA_BASE/bin 目录中的setenv.sh 文件中定义它们。

例如:

#! /bin/sh

export MAX_ACTIVE_CONNECTIONS=20

export JAVA_OPTS="$JAVA_OPTS -DmaxActiveConnections=$MAX_ACTIVE_CONNECTIONS"

并在您的 XML 配置文件中使用这些属性:

<Context path="/abc"
         docBase="abc"
         debug="5"
         reloadable="false"
         crossContext="true">
    <Resource name="jdbc/abc"
              auth="Container"
              type="javax.sql.DataSource"
              factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
              driverClassName="xxxxx"
              url="xxxxxxx"
              username="xxxxx" password="xxxxxx"
              maxActive="${maxActiveConnections}"
              initialSize="0"
              ...
    />
</Context>

【讨论】:

  • 这听起来不像是 OP 要求的编程修改
  • 非常感谢您指出@eis。抱歉,我错过了问题的那一部分。
  • 再次感谢@eis。我使用基于运行时的解决方案更新了答案。很抱歉第一次错过了运行时要求。
  • 我支持 JMX 变体。从注册表中获取 MBean 进行编程修改没有问题。另一方面,我会让连接池实现处理连接数。
【解决方案2】:

通过 JNDI 创建的数据源没有什么特别之处:如果您知道它的类(在您的情况下为 org.apache.tomcat.jdbc.pool.DataSource),则可以强制转换为该类并使用可用的设置器对其进行配置:

    private void customizeDataSource(final DataSource ds) {
        if (ds instanceof PoolConfiguration) {
            final PoolConfiguration poolConfig = (PoolConfiguration) ds;
            poolConfig.setMaxActive(10);
        }
    }

(见PoolConfiguration的定义)。 javax.sql.DataSource 的实现还实现了一个非常有用的接口 Wrapper,如果您的代码将 Tomcat JDBC 数据源包装在其他东西中,它可能会派上用场:

    private void customizeDataSource(final DataSource ds) throws SQLException {
        if (ds.isWrapperFor(PoolConfiguration.class)) {
            final PoolConfiguration poolConfig = ds.unwrap(PoolConfiguration.class);
            poolConfig.setMaxActive(10);
        }
    }

然而,上述程序化方法可能会产生一些问题:

  • 如果您将tomcat-jdbc.jar 与您的应用程序捆绑在一起,那么您的代码将仅识别在您的context.xml 中配置的JNDI 资源。 GlobalNamingResources 中的那些将使用与 Tomcat 捆绑在一起的 org.apache.tomcat.jdbc.pool.DataSource 的副本,并且不会匹配 instanceof 条件。
  • 另一方面,如果您没有在 WAR 文件中包含 tomcat-jdbc.jar,则必须确保您设置的参数受运行应用程序的所有 Tomcat 版本的支持。

【讨论】:

  • 可以通过 Java 反射访问全局命名资源。只有几个不同的数据源实现。一个人可以迭代多个可能的方法名称,直到它工作......
【解决方案3】:

MySQL 快速连接,从而限制了连接池的使用。

通常,如果存在性能问题,最好通过其他技术来处理——复合索引、重组查询、解决 MySQL 的优化限制等。

您是否愿意备份一个步骤,让我们分析一下瓶颈?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 2018-06-26
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    相关资源
    最近更新 更多