在 tomcat 容器中具有多个 Web 应用程序的 Spring Boot 执行器引发 javax.management.InstanceAlreadyExistsException 异常
Posted
技术标签:
【中文标题】在 tomcat 容器中具有多个 Web 应用程序的 Spring Boot 执行器引发 javax.management.InstanceAlreadyExistsException 异常【英文标题】:Spring Boot actuator with multiple web applications in a tomcat container throws javax.management.InstanceAlreadyExistsException exception 【发布时间】:2015-01-10 04:36:02 【问题描述】:我在一个 tomcat 容器内运行多个 Spring Boot 应用程序(不是嵌入式的 - 只是独立的 tomcat 容器)。但是,它在启动 Web 应用程序时给了我以下异常。它不会影响任何 Web 应用程序的功能,但仍然是我想解决的问题,以实现干净的启动。
非常感谢任何有关如何解决此问题的帮助。
使用 Spring Boot 1.1.7
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@14bee2f1] wit
h key 'metricsEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=metricsEndpoint
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:775)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:131)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:485)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:142)
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@1be9493f] with key 'traceEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=traceEndpoint
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@533a21cd] with key 'dumpEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=dumpEndpoint
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@695b578c] with key 'autoConfigurationAuditEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=autoConfigurationAuditEndpoint
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.ShutdownEndpointMBean@7271ef13] with key 'shutdownEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=shutdownEndpoint
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@34ea9086] with key 'configurationPropertiesReportEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=configurationPropertiesReportEndpoint
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)
【问题讨论】:
默认情况下,所有端点都在域org.springboot
下注册并使用默认名称。这些可以通过设置endpoints.jmx.*
属性来覆盖。见here。您可能想要更改每个应用程序的域或将endpoints.jmx.unique-name
设置为true
。
@M.Deinum - 非常感谢。将 unique-name 设置为 true 就可以了。端点现在将注册为什么?另外,如果您可以将此添加为答案,我会接受它,以便对其他人也有帮助。再次感谢!
我不知道实际名称是什么,可能取决于使用的底层策略。您可能需要查看 Spring Boot 的端点注册部分。
【参考方案1】:
默认情况下,所有端点都在域org.springboot
下注册并使用默认名称。这些可以通过设置endpoints.jmx.*
属性来覆盖。见here。
您可能希望更改每个应用程序的域或将 endpoints.jmx.unique-names
设置为 true。
【讨论】:
【参考方案2】:通过添加以下属性在 application.properties 中禁用 JMX
spring.jmx.enabled = false
【讨论】:
这将使应用程序运行但不会解决问题 请参阅下面@bigbadmouse 的答案,以更详细地了解其工作原理。它帮助了我。就我而言,我在尝试运行单元测试时得到了InstanceAlreadyExistsException
,因此我将spring.jmx.enabled = false
行添加到我的src/test/resources/application.properties
文件中。【参考方案3】:
唯一名称对我不起作用。我还必须添加一个默认域。
这是我的 yml 代码
spring:
jmx:
default-domain: agentservice
endpoints:
jmx:
domain: agentservice
unique-names: true
【讨论】:
【参考方案4】:为了补充我投票赞成的 Gondy 的答案,下面是一个链接,正是说明了它的工作原理。 PhilWebb 说 “事实证明,如果您使用 Spring 的测试上下文框架,默认注册 JMX 信息会导致一些问题。.. 默认情况下,使用 @ContextConfiguration 的测试保持上下文打开” 和 “我认为我们需要将 spring.datasource.jmx-enabled 更改为默认为 false 并使其选择加入"
见GitHub(在“philwebb 于 2014 年 11 月 7 日发表评论”)
我很欣赏这不是一个独特的答案。但是这个问题已经困扰了我一段时间,Gondy 的回答帮助了我,然后我发现了原因并想以我唯一可用的方式分享这些额外的信息
【讨论】:
感谢您的解释,@Gondy 的回答也对我有所帮助,但我希望他能添加更多信息。这很有帮助。【参考方案5】:spring:
jmx:
default-domain: agentservice
endpoints:
jmx:
domain: agentservice
unique-names: true
在同一个 JVM 上部署多个实例时与我一起使用上述配置
【讨论】:
【参考方案6】:在单个 Tomcat 服务器上部署多个 web 应用程序(在我的情况下为 Spring Boot)时,由于 javax.management.InstanceAlreadyExistsException,我收到了这个错误 org.springframework.jmx.export.UnableToRegisterMBeanException。 在网上搜索了一番后,我发现了这个: “spring.jmx.enabled 设置为 true(默认值),上下文中的任何 MBean bean 都将自动注册到 JMX 服务器。” 来源:https://github.com/spring-projects/spring-boot/issues/9179
选项是:
Option-1) 设置 spring.jmx.enabled=false 来源:https://github.com/spring-projects/spring-boot/issues/9179
选项 2) 为每个部署的 web 应用程序为 JMX bean 提供唯一的名称 spring.jmx.default-domain:app1 spring.jmx.default-domain: app2 来源:https://github.com/jhipster/generator-jhipster/issues/874
Option-3) 在每个 webapp 中更改 bean 本身的名称 @豆 公共数据源 app1DataSource() ... @豆 公共数据源 app2DataSource() ...
【讨论】:
以上是关于在 tomcat 容器中具有多个 Web 应用程序的 Spring Boot 执行器引发 javax.management.InstanceAlreadyExistsException 异常的主要内容,如果未能解决你的问题,请参考以下文章