1. 程式人生 > >使用阿里巴巴資料來源和log4j注意的事項

使用阿里巴巴資料來源和log4j注意的事項

這個也是一個小知識。之前我發過一個資源空白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,都講完了。