You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式ActiveMQ Artemis远程JMX连接失败问题求助

解决嵌入式ActiveMQ Artemis 2.38.0 + JMX远程连接问题(Spring Boot 3.x/Java 17)

核心问题分析

你遇到的连接拒绝错误,本质是嵌入式Artemis默认未启用远程JMX访问,再加上Java 17对RMI连接的严格限制、Spring Boot 3.x的JMX自动配置可能冲突,导致JMX服务无法被远程访问。

分步解决方案

1. 完善嵌入式Artemis的JMX配置

修改嵌入式服务器初始化代码,显式开启远程JMX并配置RMI端口:

Configuration mqConfig = new ConfigurationImpl();
server = new EmbeddedActiveMQ();

// 原有配置
mqConfig.addAcceptorConfiguration("tcp", "tcp://127.0.0.1:61616");
mqConfig.setSecurityEnabled(false);
mqConfig.setMessageCounterEnabled(true);
mqConfig.setMessageCounterSamplePeriod(500);
mqConfig.setMessageCounterMaxDayHistory(1);

// 新增JMX远程配置
mqConfig.setJMXManagementEnabled(true);
mqConfig.setJMXRemoteManagementEnabled(true); // 关键:开启远程JMX
mqConfig.setRMIRegistryPort(1099); // RMI注册中心端口
mqConfig.setRMIServerPort(1098); // RMI服务器端口(需与注册端口不同)
mqConfig.setManagementAddress("localhost");
mqConfig.setManagementNotificationAddress("localhost");

server.setConfiguration(mqConfig);
server.start();

2. 配置Java 17的RMI系统属性

Java 17对RMI连接的主机名解析有严格限制,需在测试启动前设置以下系统属性(可在代码中设置,或通过测试启动参数传递):

// 在启动EmbeddedActiveMQ之前添加
System.setProperty("java.rmi.server.hostname", "localhost");
System.setProperty("com.sun.management.jmxremote.authenticate", "false");
System.setProperty("com.sun.management.jmxremote.ssl", "false");

3. 避免Spring Boot 3.x的JMX自动配置冲突

Spring Boot 3.x默认会启用自身的JMX配置,可能占用1099端口,导致Artemis的RMI注册中心无法启动。解决方式二选一:

  • 禁用Spring Boot的JMX自动配置:在测试类上添加注解:
    @EnableAutoConfiguration(exclude = {JmxAutoConfiguration.class})
    
  • 修改Spring Boot的JMX端口:在application-test.properties中配置:
    spring.jmx.enabled=true
    spring.jmx.server.port=1100 # 与Artemis的1099端口错开
    

4. 正确的JMX连接与队列深度获取代码

修改JMX连接代码,确保使用正确的服务URL,并通过QueueControl MBean获取队列深度:

// 注意:如果修改了RMIServerPort,URL无需变更,注册中心会引导到正确的服务器端口
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

// 队列的MBean名称格式:org.apache.activemq.artemis:broker=<brokerName>,component=addresses,address=<addressName>,subcomponent=queues,routing-type=<routingType>,queue=<queueName>
// 嵌入式Artemis默认brokerName为"0",routingType默认"anycast"(点对点队列)
ObjectName queueObjectName = new ObjectName("org.apache.activemq.artemis:broker=0,component=addresses,address=yourQueueAddress,subcomponent=queues,routing-type=anycast,queue=yourQueueName");

QueueControl queueControl = JMX.newMBeanProxy(mbsc, queueObjectName, QueueControl.class);
// 获取队列深度(未消费消息数)
long messageCount = queueControl.getMessageCount();
System.out.println("Queue depth: " + messageCount);

jmxc.close();

关键注意事项

  • 嵌入式Artemis的默认broker名称是0,如果自定义了broker名称,需要在MBean名称中替换对应的broker=<yourBrokerName>。
  • 队列的address名称需与创建队列时指定的address一致(Artemis中队列属于某个address)。
  • 确保测试代码中Artemis服务器完全启动后,再发起JMX连接(可通过server.waitForActivation()等待服务器就绪)。

内容的提问来源于stack exchange,提问作者user28089685

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:10:17