介绍
FlexyPool是一个开放源代码框架,可以监视数据源连接的使用情况。 由于我们以前缺乏对供应连接池的支持,因此该工具是不必要的。
FlexyPool最初是为独立环境设计的,并且DataSource代理配置是通过编程完成的。 使用Spring bean别名 ,我们甚至可以将已经配置的DataSource替换为FlexyPool Metrics感知的代理替代方案。
Java EE支持
最近,有人问我如何支持Java EE环境,本着真正的开源精神,我接受了挑战。 支持托管环境非常棘手,因为数据源已与应用程序逻辑完全分离,并且可以通过JNDI查找来使用。
一个缺点是我们不能使用自动池大小调整策略,因为大多数应用服务器返回自定义的DataSource实现(与其内部JTA事务管理器解决方案紧密集成),因此无法访问读/写连接池大小。
尽管DataSource可能无法调整,但我们至少可以监视连接使用情况,这也足以支持Java EE环境。
添加声明性配置
因为我们在托管环境中运行,所以我们无法再以编程方式配置DataSource,因此我们需要使用声明性配置支持。
默认情况下,FlexyPool在当前的类路径中查找flexy-pool.properties文件。 可以使用flexy.pool.properties.path系统属性来自定义位置,该属性可以是:
- URL(例如文件:/ D:/wrk/vladmihalcea/flexy-pool/flexy-pool-core/target/test-classes/flexy-pool.properties )
- 文件系统路径(例如D:\ wrk \ vladmihalcea \ flexy-pool \ flexy-pool-core \ target \ test-classes \ flexy-pool.properties )
- 类路径嵌套路径(例如nested / fp.properties )
该属性文件可能包含以下配置选项:
参数名称 | 描述 |
---|---|
flexy.pool.data.source.unique.name | 每个FlexyPool实例都需要一个唯一的名称,以便JMX域不会冲突 |
flexy.pool.data.source.jndi.name | JNDI数据源位置 |
flexy.pool.data.source.jndi.lazy.lookup | 是否延迟查找数据源(当实例化FlexyPoolDataSource时目标数据源不可用时很有用) |
flexy.pool.data.source.class.name | 可以使用此类名称在运行时实例化数据源 |
flexy.pool.data.source.property。* | 如果在运行时实例化了DataSource,则每个flexy.pool.data.source.property。$ {java-bean-property}将设置新实例化的DataSource的java-bean-property(例如flexy.pool.data.source。 property.user = sa) |
flexy.pool.adapter.factory | 如果数据源支持动态调整大小,则指定PoolAdaptorFactory。 默认情况下,它使用不支持自动缩放的通用DataSourcePoolAdapter |
flexy.pool.metrics.factory | 指定用于创建指标的MetricsFactory |
flexy.pool.metrics.reporter.log.millis | 指定指标日志报告间隔 |
flexy.pool.metrics.reporter.jmx.enable | 指定是否应启用JMX报告 |
flexy.pool.metrics.reporter.jmx.auto.start | 指定是否应自动启动jmx服务(在Java EE环境中将其设置为true) |
flexy.pool.strategies.factory.resolver | 指定一个ConnectionAcquiringStrategyFactoryResolver类,该类用于获取ConnectionAcquiringStrategyFactory对象的列表。 仅当PoolAdaptor支持访问数据源池大小时,才应设置此值。 |
休眠连接提供者
大多数Java EE应用程序已经在使用JPA ,对于碰巧正在使用Hibernate的用户,我们可以使用hibernate.connection.provider_class配置属性来注入我们的代理数据源。
Hibernate提供了许多内置的扩展点,并且连接管理是完全可配置的。 通过提供一个自定义的ConnectionProvider,我们可以用FlexyPool代理替换原始的DataSource。
我们要做的就是将以下属性添加到我们的persistence.xml文件中:
<property name="hibernate.connection.provider_class"value="com.vladmihalcea.flexypool.adaptor.FlexyPoolHibernateConnectionProvider"/>
在后台,此提供程序将配置FlexyPoolDataSource并在需要新连接时使用它:
private FlexyPoolDataSource<DataSource> flexyPoolDataSource;@Override
public void configure(Map props) {super.configure(props);LOGGER.debug("Hibernate switched to using FlexyPoolDataSource");flexyPoolDataSource = new FlexyPoolDataSource<DataSource>(getDataSource());
}@Override
public Connection getConnection() throws SQLException {return flexyPoolDataSource.getConnection();
}
在运行时实例化实际的数据源
如果您不使用Hibernate,则需要在EntityManagerFactory完成引导之前准备好FlexyPoolDataSource:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"><persistence-unit name="persistenceUnit" transaction-type="JTA"><provider>org.hibernate.jpa.HibernatePersistenceProvider</provider><jta-data-source>java:global/jdbc/flexypool</jta-data-source><properties><property name="hibernate.hbm2ddl.auto" value="update"/><property name="hibernate.show_sql" value="true"/><property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/><property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/></properties></persistence-unit>
</persistence>
在生产Java EE环境中,我们使用特定于应用程序服务器的DataSource配置,为简单起见,我将使用DataSourceDefinition批注配置FlexyPooldataSource:
@DataSourceDefinition(name = "java:global/jdbc/flexypool",className = "com.vladmihalcea.flexypool.FlexyPoolDataSource")
@Stateless
public class FlexyPoolDataSourceConfiguration {}
现在,我们需要将实际的DataSource属性传递给FlexyPool,这是通过flexy-pool.properties配置文件完成的:
flexy.pool.data.source.unique.name=unique-name
flexy.pool.data.source.class.name=org.hsqldb.jdbc.JDBCDataSource
flexy.pool.data.source.property.user=sa
flexy.pool.data.source.property.password=
flexy.pool.data.source.property.url=jdbc:hsqldb:mem:test
flexy.pool.metrics.reporter.jmx.auto.start=true
实际的数据源将在启动时由FlexyPoolDataSource创建。
从JNDI找到实际的数据源
如果实际的数据源已经由Application Server配置,我们可以指示FlexyPool从JNDI获取它。 假设我们具有以下DataSource配置:
@DataSourceDefinition(name = "java:global/jdbc/default",className = "org.hsqldb.jdbc.JDBCDataSource",url = "jdbc:hsqldb:mem:test",initialPoolSize = 3,maxPoolSize = 5
)
@Stateless
public class DefaultDataSourceConfiguration {}
要代理JNDI数据源,我们需要像这样配置FlexyPool:
flexy.pool.data.source.unique.name=unique-name
flexy.pool.data.source.jndi.name=java:global/jdbc/default
flexy.pool.metrics.reporter.jmx.auto.start=true
FlexyPoolDataSource与实际的DataSource一起定义:
@DataSourceDefinition(name = "java:global/jdbc/flexypool",className = "com.vladmihalcea.flexypool.FlexyPoolDataSource")
@Stateless
public class FlexyPoolDataSourceConfiguration {}
JPA必须获取FlexyPoolDataSource而不是实际的:
<jta-data-source>java:global/jdbc/flexypool</jta-data-source>
在TomEE中 ,因为未延迟实例化DataSourceDefinitions,所以在处理FlexyPoolDataSource定义时,实际的DataSource在JNDI注册表中可能不可用。
为此,我们需要指示FlexyPool依赖JNDI查找,直到实际请求了DataSource为止:
flexy.pool.data.source.jndi.lazy.lookup=true
结论
我上一次使用Java EE是在2008年,一个使用Java EE 1.4和EJB 2.1的项目。 在专门使用Spring 7年之后,我对Java EE的使用感到惊讶。 Arquillian绝对是我最喜欢的插件,因为集成测试在企业应用程序中至关重要。 CDI既简单又强大,我很高兴对依赖注入进行了标准化。
但是Java EE平台的最佳资产是社区本身。 Java EE具有非常强大的社区,愿意在需要时为您提供帮助。 我要感谢Steve Millidge(Payara和C2B2的创始人)为我提供了一些有关设计FlexyPool Java EE集成的重要技巧, Alex Soto , Antonio Goncalves , Markus Eisele以及我感兴趣的所有其他Java EE成员Twitter上的对话。
翻译自: https://www.javacodegeeks.com/2015/06/how-to-monitor-a-java-ee-datasource.html