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

Docker容器中运行ActiveMQ Artemis时无法连接JMX

问题描述

我有一个Java客户端,当它与ActiveMQ Artemis运行在同一台机器上时,能够成功连接到ActiveMQ Artemis JMX。客户端代码如下:

public static void main(String[] args) throws IOException, MalformedObjectNameException, ReflectionException, AttributeNotFoundException, InstanceNotFoundException, MBeanException 
{    
    private static final String JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi";
    System.out.println("Hello, Artemis!");
    HashMap env = new HashMap();
    String[] creds = {"artemis", "artemis"};
    env.put(JMXConnector.CREDENTIALS, creds);
    JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), env);  
    MBeanServerConnection mBeanServer = connector.getMBeanServerConnection();    
    System.out.println("Connected to the server");
}

将ActiveMQ Artemis部署到已暴露必要端口的Docker容器中后,出现以下错误:

java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: error during JRMP connection establishment;

已尝试的操作:

  • 在Docker中暴露JMX端口
  • 在artemis.profile中添加Java参数(-Djava.rmi.server.hostname=localhost)
  • 在management.xml中启用Connector元素(<connector connector-port="1099" connector-host="localhost"/>),也尝试将localhost替换为0.0.0.0,但问题仍存在
  • 本地构建并运行Docker镜像后,确认RMI注册表正在监听端口1099,但仍无法连接

解决方案

Docker环境下JMX/RMI连接失败的核心原因是RMI的双重端口机制:除了1099的注册表端口,RMI服务本身会默认使用随机端口,而Docker仅暴露了你指定的1099端口,导致客户端无法连接到随机端口;另外java.rmi.server.hostname配置错误会让客户端拿到容器内部地址,无法正常访问。

具体解决步骤:

  1. 修正JVM参数,固定端口并配置外部可访问地址
    修改artemis.profile中的Java参数,替换原有的-Djava.rmi.server.hostname=localhost,添加以下配置:
-Djava.rmi.server.hostname=<宿主机IP或外部可访问域名>
-Dcom.sun.management.jmxremote.port=1099
-Dcom.sun.management.jmxremote.rmi.port=1099
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=false
  • java.rmi.server.hostname必须设置为客户端能直接访问到的宿主机IP/域名,不能用localhost或0.0.0.0,否则客户端会拿到容器内部地址,无法建立连接。
  • com.sun.management.jmxremote.rmi.port设置为和注册表端口1099一致,避免随机端口,只需暴露1099端口即可。
  1. 调整management.xml配置
    确保容器内部服务监听所有网卡:
<connector connector-port="1099" connector-host="0.0.0.0"/>
  1. 修改客户端连接地址
    将客户端代码中的localhost替换为宿主机IP:
private static final String JMX_URL = "service:jmx:rmi:///jndi/rmi://<宿主机IP>:1099/jmxrmi";
  1. 确认Docker端口映射
    启动容器时,确保1099端口正确映射:
docker run -p 1099:1099 <你的Artemis镜像名>
  1. 验证连通性
    先在客户端机器上用telnet <宿主机IP> 1099测试端口是否可达,再运行客户端代码尝试连接。

关键注意点
  • 必须将jmxremote.rmi.port和jmxremote.port设为同一值,避免额外暴露随机端口。
  • 不要混淆容器内部的localhost和宿主机的localhost,客户端连接时必须使用宿主机的可访问地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:55:58