programing

Spring Boot 애플리케이션을 종료하는 동안 DataSource JMX Mean의 등록을 취소하지 못함

jooyons 2023. 6. 24. 09:02
반응형

Spring Boot 애플리케이션을 종료하는 동안 DataSource JMX Mean의 등록을 취소하지 못함

org.apache.commons.dbcp2를 사용하는 간단한 Spring Boot 애플리케이션이 있습니다.dataSource bean으로서의 BasicDataSource.

데이터 소스는 Spring boot에 의해 MBean으로 자동으로 노출됩니다.

콩 선언:

@Bean
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setUrl(dbUrl);
    dataSource.setDriverClassName(jdbcDriver);
    dataSource.setUsername(dbUserName);
    dataSource.setPassword(dbPassword);
    return dataSource;
}

모든 것이 잘 작동합니다.하지만 애플리케이션을 종료하는 동안 오류가 발생합니다.이 오류는 실행 파일 병을 실행할 때만 발생합니다.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.어떻게 이 콩이 JMXMean으로 노출되나요? 2. 이 MBean을 제대로 등록 해제하는 방법은?

Spring이 Basic DataSource를 두 번 닫으려고 합니다.

  1. 응용 프로그램이 닫힐 때 기본 데이터 소스가 자동으로 닫힙니다.
  2. Spring 기본 파기 방법을 사용하여 DataSource를 닫았지만 이미 닫혔습니다.

이 문제를 방지하려면 다음을 사용합니다.

@Bean(destroyMethod = "")
public DataSource dataSource() 

Java 구성에서

저도 같은 문제에 부딪혔습니다.MBean 서버를 추가하고 데이터 소스를 등록해도 해결할 수 없습니다.

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jmx.html

제 결론은 DBCP2의 Basic DataSource가 MBean 서버에서 자체 등록을 취소하는 버그가 있다는 것입니다.

mchange의 c3p0: http://www.mchange.com/projects/c3p0/ 로 전환하여 내 것을 고쳤습니다.

BasicDataSource extends BasicDataSourceMXBean그래서 그것은 JMX 서버에 MBean으로 자동 등록됩니다.[org.apache.commons.dbcp2:name=dataSource,type=BasicDataSource]springboot이 종료되면 MBeanExporter가 MBean의 등록을 취소한 다음 springboot가 제거를 시도합니다.BasicDataSourceBasicDataSource의 메서드를 호출합니다.close()MBean을 다시 등록 취소합니다(Basic DataSource가 JME 예외를 포착하고 이 경고를 인쇄합니다).그냥 경고야.인쇄를 원하지 않는 경우 스프링 부트에서 JMX를 사용하지 않도록 설정할 수 있습니다.

application.yml
spring:
jmx:
enabled: false

저도 같은 문제가 있었습니다.c3p0는 매우 잘 작동합니다.

사용하는 경우에는spring frameworkpom.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보다 더 빨리 수행됩니다.

이것이 조금이나마 도움이 되길 바랍니다.건배!

언급URL : https://stackoverflow.com/questions/24947717/failed-to-unregister-datasource-jmx-mbean-while-shutting-down-a-spring-boot-appl

반응형