DataSource Beanとしてorg.Apache.commons.dbcp2.BasicDataSourceを使用する簡単なSpring Bootアプリケーションがあります。
データソースは、Springブートによって自動的にMBeanとして公開されます。
Bean宣言:
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl(dbUrl);
dataSource.setDriverClassName(jdbcDriver);
dataSource.setUsername(dbUserName);
dataSource.setPassword(dbPassword);
return dataSource;
}
すべてが正常に動作します。しかし、アプリケーションのシャットダウン中にエラーが表示されます。このエラーは、実行可能jarを実行しているときにのみ発生します。 Gradle Springプラグイン(gradle bootRun)を使用している場合、これは表示されません。
javax.management.InstanceNotFoundException: org.Apache.commons.dbcp2:name=dataSource,type=BasicDataSource
at com.Sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.Java:1095)
at com.Sun.jmx.interceptor.DefaultMBeanServerInterceptor.exclusiveUnregisterMBean(DefaultMBeanServerInterceptor.Java:427)
at com.Sun.jmx.interceptor.DefaultMBeanServerInterceptor.unregisterMBean(DefaultMBeanServerInterceptor.Java:415)
at com.Sun.jmx.mbeanserver.JmxMBeanServer.unregisterMBean(JmxMBeanServer.Java:546)
at org.Apache.commons.dbcp2.BasicDataSource.close(BasicDataSource.Java:1822)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
at Java.lang.reflect.Method.invoke(Method.Java:483)
at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.Java:350)
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.Java:273)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.Java:540)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.Java:516)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.Java:827)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.Java:485)
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.Java:921)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.Java:895)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.doClose(EmbeddedWebApplicationContext.Java:152)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.Java:809)
1.このBeanはどのようにJMX MBeanとして公開されますか? 2.このMBeanを適切に登録解除するにはどうすればよいですか?
SpringはBasicDataSourceを2回閉じようとしています:
これを回避するには、以下を使用します。
@Bean(destroyMethod = "")
public DataSource dataSource()
あなたのJava設定で
_BasicDataSource extends BasicDataSourceMXBean
_、つまり、MBean _[org.Apache.commons.dbcp2:name=dataSource,type=BasicDataSource]
_としてJMXサーバーに自動登録されます。 springbootがシャットダウンすると、MBeanExporterはMBeanの登録を解除し、次にBasicDataSource
を破棄してBasicDataSourceのメソッドclose()
を呼び出し、MBeanの登録を解除します(BasicDataSourceはJMExceptionをキャッチして、この警告を出力します)。これは単なる警告です。印刷したくない場合は、springbootでJMXを無効にすることができます。
_application.yml
spring:
jmx:
enabled: false
_
私も同じ問題に遭遇しました。 MBeanサーバーを追加してデータソースを登録しても修正できません。
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jmx.html
私の結論は、DBCP2のBasicDataSourceには、MBeanサーバーからの登録を解除する際のバグがあるということです。
私はmchangeのc3p0に切り替えることで私の問題を修正しました: http://www.mchange.com/projects/c3p0/
同じ問題がありました。 c3p0は非常にうまく機能します。
spring framework
を使用している場合-pom.xml
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
最初に使用された
DataSource ds_unpooled = DataSources.unpooledDataSource(persistenceUrl,
persistenceUsername,
persistencePassword);
return DataSources.pooledDataSource(ds_unpooled);
しかし、それは私が実行する必要がある負荷を処理できず、次のように切り替えました
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( persistenceDriver ); //loads the jdbc driver
cpds.setJdbcUrl( persistenceUrl );
cpds.setUser(persistenceUsername);
cpds.setPassword(persistencePassword);
cpds.setMinPoolSize(5);
cpds.setMaxPoolSize(50);
cpds.setUnreturnedConnectionTimeout(1800);
cpds.setMaxStatements(50);
cpds.setMaxIdleTime(21600);
cpds.setIdleConnectionTestPeriod(10800);
return cpds;
これらの値は、私がオンラインで収集した他の投稿からのものです。
私の特定のタスクの経験では、c3p0を実行すると、同じ環境でdbcp2 v:2.1.1よりも高速に実行されます。
これが少し役に立てば幸いです。乾杯!