Druid register mbean error

本文分析了Druid数据库连接池在长时间运行后出现MBean注册失败的问题,探讨了其根本原因并提供了相应的解决策略。
key: [com.alibaba.druid.stat.DruidDataSourceStatManager.addDataSource(DruidDataSourceStatManager.java:154)]  register mbean error

在使用数据库连接池时(本文通用于其他使用jmx mbean的应用),运行几天后出现如下错误

2014/11/18 10:31:00,617 [ERROR] [localhost-startStop-6] [com.alibaba.druid.stat.DruidDataSourceStatManager.addDataSource(DruidDataSourceStatManager.java:154)]  register mbean error
javax.management.InstanceAlreadyExistsException: com.alibaba.druid:type=DruidDataSource,id=Druid MySQL DB pool
        at com.sun.jmx.mbeanserver.Repository.addMBean(Repository.java:453)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.internal_addObject(DefaultMBeanServerInterceptor.java:1484)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:963)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:917)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:312)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:482)
        at com.alibaba.druid.stat.DruidDataSourceStatManager.addDataSource(DruidDataSourceStatManager.java:152)
        at com.alibaba.druid.pool.DruidDataSource$1.run(DruidDataSource.java:1298)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.alibaba.druid.pool.DruidDataSource.registerMbean(DruidDataSource.java:1294)
        at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:623)
        at com.longdai.data.ConnectionManagerDruid.<init>(ConnectionManagerDruid.java:68)
        at com.longdai.data.ConnectionManager.getInstance(ConnectionManager.java:86)
        at com.longdai.data.dao.Database.<clinit>(Database.java:22)
        at com.longdai.service.admin.CloseNetWorkService.getNetWorkById(CloseNetWorkService.java:87)
        at com.longdai.service.admin.CloseNetWorkService$$FastClassByCGLIB$$bbdb465c.invoke(<generated>)
        at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
        at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        at com.gozap.services.ServiceMethodInterceptor.invoke(ServiceMethodInterceptor.java:31)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
        at com.longdai.service.admin.CloseNetWorkService$$EnhancerByCGLIB$$19cbebaf.getNetWorkById(<generated>)
        at com.longdai.system.listener.CloseNetWorkConfigiListener.contextInitialized(CloseNetWorkConfigiListener.java:37)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4791)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5285)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:618)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:963)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1600)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)
查看源码,一直跟踪到

at com.sun.jmx.mbeanserver.Repository.addMBean(Repository.java:453)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.internal_addObject(DefaultMBeanServerInterceptor.java:1484) // 这里
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:963)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:917)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:312) //这里入口

一路跟踪源码,传入的参数一直是name属性,查看上层 DruidDataSourceStatManager.java  addDataSource(Object dataSource, String name) 

在看上层: DruidDataSource.java line:1298


这里传入了数据源的name属性,经过上面的分析,是利用DataSource的name属性拼接成一个id,然后用次id注册mbean, 然而,druid的name属性写成了一个默认值


故此注册失败。


现在知道了原因,为什么运行几天后才出现这个错误,并且运维说有回滚到了上个版本,在部署(直接重新部署,并没有重启tomcat/jvm)的时候就直接报这个错误,经过上面的推断是jvm中已经有一个此id的mbean了,故此即使重新部署还是失败,我给想了个办法,重启tomcat,搞定,果然奏效。

在来看看druid的wiki中,虽然提示了配置name属性,但是在配置文件中配置后是不起作用的,经过查看源码发现并没有加载次属性,所以配置了没用,后来我在代码中获取配置文件的name属性,然后dataSource.setName(name),虽然名字设置成功了,在druid的监控页面也可以看的自定义的名字,但是不幸的是druid运行几天出错了或者重新部署,然后重新向jvm注册mbean,导致了出错。

再来看看datasource的name的默认值是怎么设置的DruidAbstractDataSource.java line: 849


可以看到在getName属性中是DataSource-加上计算的一个hash值,但是此方法只在getName时返回,而在注册mbean时druid的name默认是null, 在注册mbean时分析下面的代码DruidDataSourceStatManager.java line: 161


代码显示是根据dataSource计算出来莪一个hash值,然后进行注册mbean。


经过上面的分析在注册mbean时,一定要保证registerMBean的name参数唯一,还要在上层拦截异常

InstanceAlreadyExistsException,然后自动处理异常

总结:在使用Druid的时候,不要使用name属性,druid官网并没有给出说明,本文在此给大家一个解释和处理方法。另外1.0.5版本配置后是不起作用的,需要自己强行setName。如自己配置了name,为防止出错,最好修改Druid源码  DruidDataSourceStatManager.java  addDataSource(Object dataSource, String name) ,在生成objectName是在加一个 hash(参考161)。另外大家在注册MBean时,一定要保证id的唯一,以及重复的处理方式。如果出现了这个错误,就将与本项目使用的同一个jvm的项目都关掉,清理掉本jvm,然后重启服务


附: https://github.com/alibaba/druid


<think>我们正在处理用户关于Druid构建错误的问题。由于用户的问题是关于Druid构建错误的解决方案,我们需要提供详细的解决步骤。 注意:由于我们无法直接访问外部网络,因此我们只能根据已有的知识和常见的构建错误原因来提供建议。 常见的Druid构建错误可能包括: 1. 依赖下载失败(网络问题或仓库配置问题) 2. 环境问题(Java版本不匹配,Maven版本过低等) 3. 代码版本问题(分支不稳定,代码冲突等) 4. 本地环境配置问题(内存不足,权限问题等) 我们将提供一般性的解决步骤,并建议用户根据具体错误信息进行排查。 回答结构: 1. 确认问题:描述用户遇到的问题(构建Druid时出现错误) 2. 提供通用解决步骤 3. 建议查看具体错误日志并给出常见错误的解决方法 4. 建议用户如果问题仍然存在,可以提供具体的错误信息以便进一步帮助 由于用户的问题比较简短,我们无法得知具体的错误信息,因此需要提供通用的排查方法。 注意:在回答中,我们可能会引用一些常见的Druid构建问题解决方案,但如果没有具体的引用来源,我们将不添加引用标识。如果我们的回答基于一般性的知识,则无需引用。 由于用户要求使用中文回答,我们将用中文撰写。</think>### Druid构建错误解决方案 构建Druid时常见的错误通常与依赖管理、环境配置或构建工具相关。以下是系统性的解决步骤: #### 1. **验证基础环境** - **Java版本**:确保使用Java 8或11(Druid官方推荐版本) ```bash java -version ``` 若版本不符,使用`update-alternatives`切换版本或安装正确JDK - **Maven版本**:需≥3.5.0 ```bash mvn -v ``` #### 2. **解决依赖问题** - **清理本地仓库**(常见于依赖冲突): ```bash mvn clean install -U -DskipTests ``` 其中`-U`强制更新快照依赖,`-DskipTests`跳过测试加速构建 - **网络问题**:检查Maven镜像配置(`~/.m2/settings.xml`),建议使用阿里云镜像: ```xml <mirror> <id>aliyun</id> <url>https://maven.aliyun.com/repository/public</url> <mirrorOf>central</mirrorOf> </mirror> ``` #### 3. **处理常见构建错误** - **"Could not resolve dependencies"**: ```bash # 删除冲突依赖 rm -rf ~/.m2/repository/org/apache/druid/ mvn dependency:purge-local-repository ``` - **内存不足**:扩大Maven堆内存 ```bash export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512m" ``` - **原生库问题**(如`io.netty`): ```bash mvn clean install -DskipTests -Dmaven.javadoc.skip=true -Dskip.npm ``` #### 4. **特定模块构建** 若整体构建失败,可尝试单独构建模块: ```bash # 例如仅构建核心模块 mvn install -pl druid-core -am -DskipTests ``` #### 5. **日志分析技巧** 定位错误日志中的关键信息: - `[ERROR] Failed to execute goal ...`:查看目标名称(如`maven-compiler-plugin`) - `Caused by:`:根源异常(如`ClassNotFoundException`) - 搜索`[WARNING]`排除次要干扰 > **重要提示**:若使用Docker构建,确保挂载`.m2`目录缓存依赖: > ```dockerfile > VOLUME /root/.m2 # 持久化Maven仓库 > ``` ### 典型错误案例参考 1. **Java版本不匹配**:报错`Unsupported class file major version`需切换JDK[^1] 2. **Guava冲突**:添加依赖排除 ```xml <exclusion> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </exclusion> ``` 3. **时间戳错误**:虚拟机时钟不同步导致`Invalid timestamp`,运行`ntpdate`同步时间
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值