使用阿里巴巴資料來源和log4j注意的事項
阿新 • • 發佈:2018-12-23
這個也是一個小知識。之前我發過一個資源空白maven web專案,直接寫業務程式碼即可。本來以為有了這個模板,以後直接寫業務程式碼就行了。但是我使用這個模板做了兩個不同的應用部署在同一臺TOMCAT下面,發現一個應用可以使用,另外一個卻不可以。也就是說這兩個應用,如果單獨部署的時候都可以使用,但是部署在一起的時候,只能使用其中一個,我就感覺到應該是相互影響。
使用阿里巴巴資料來源出現的問題
一開始,我以為是這兩個專案的spring-mybatis.xml檔案中bean id的值一樣引起的,例如下面的程式碼:
然後我就將這些名字改成不一樣的,結果還是不行。<bean id="dataSource" class="com.aotain.time.datasource.RoutingDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry value-ref="timeManageDataSource" key="timeManage"></entry> </map> </property> <property name="defaultTargetDataSource" ref="timeManageDataSource"></property> </bean>
後來我通過先部署一個,再部署另外一個,然後去檢視tomcat日誌的方式,發現了一下錯誤資訊:
javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidDataSourceStat 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 com.alibaba.druid.stat.DruidDataSourceStatManager.removeDataSource(DruidDataSourceStatManager.java:200) at com.alibaba.druid.pool.DruidDataSource$2.run(DruidDataSource.java:1396) at java.security.AccessController.doPrivileged(Native Method) at com.alibaba.druid.pool.DruidDataSource.unregisterMbean(DruidDataSource.java:1392) at com.alibaba.druid.pool.DruidDataSource.close(DruidDataSource.java:1353) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) 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:578) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554) at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:900) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523) at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:907) at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:908) at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:884) at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:836) at org.springframework.web.context.ContextLoader.closeWebApplicationContext(ContextLoader.java:579) at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:115) at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:5156) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5829) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:221) at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1716) at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1705) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) [CONSOLE] 2018-03-07 10:47:58,881 ERROR com.alibaba.druid.stat.DruidStatService - unregister mbean error javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidStatService 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 com.alibaba.druid.stat.DruidStatService.unregisterMBean(DruidStatService.java:366) at com.alibaba.druid.stat.DruidDataSourceStatManager.removeDataSource(DruidDataSourceStatManager.java:205) at com.alibaba.druid.pool.DruidDataSource$2.run(DruidDataSource.java:1396) at java.security.AccessController.doPrivileged(Native Method) at com.alibaba.druid.pool.DruidDataSource.unregisterMbean(DruidDataSource.java:1392) at com.alibaba.druid.pool.DruidDataSource.close(DruidDataSource.java:1353) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) 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:578) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554) at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:900) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523) at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:907) at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:908) at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:884) at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:836) at org.springframework.web.context.ContextLoader.closeWebApplicationContext(ContextLoader.java:579) at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:115) at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:5156) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5829) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:221) at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1716) at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1705) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745)
後來我參考這邊文章 解決ERROR - unregister mbean error javax.management.InstanceNotFoundException: com.alibaba.druid:type= 修改tomcat的bin目錄下的catalina.sh檔案,在# OS specific support. $var _must_ be set to either true or false.與cygwin=false之間加上JAVA_OPTS="-Ddruid.registerToSysProperty=true"就OK了
使用log4j還有個小的注意事項:
首先,如果對log4j不是很瞭解的話可以檢視 log4j.properties配置詳解與例項。然後在web.xml中配置
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>Application</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:conf/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>10000</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
當然也要匯入對應的jar包,手動加入或者新增pom.xml都可以
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
在log4j配置的時候,讀取的是wbe.xml裡webAppRootKey屬性下的值,而不是webAppRootKey。這個要是太久不用的話可能會忘記。
比如:
### 系統成功日誌 ###
log4j.appender.SUCCESS = org.apache.log4j.DailyRollingFileAppender
log4j.appender.SUCCESS.File = ${Application}/logs/success/success
log4j.appender.SUCCESS.Append = true
log4j.appender.SUCCESS.Threshold = INFO
log4j.appender.SUCCESS.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.SUCCESS.layout = org.apache.log4j.PatternLayout
log4j.appender.SUCCESS.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t ] %m%n
還有個注意事項,同一個tomcat下的的兩個應用,webAppRootKey屬性下的值最好不要相同,因為這可能會導致這個應用的日誌列印到另外一個應用log目錄下(大家有空的時候可以自我探究下)。
OK,都講完了。