简体   繁体   English

无法远程连接到 jmx 端口

[英]unable to connect to jmx port remotely

I'm trying to connect to a jmx port remotely but I can't seem to connect to it even though the port is open.我正在尝试远程连接到 jmx 端口,但即使端口已打开,我似乎也无法连接到它。 Its a java process running in a container on a server thats a Nomad worker.它是一个在服务器上的容器中运行的 java 进程,它是一个 Nomad 工作者。 Its running on 29406 .它在29406运行。

Here is what netstat shows:这是netstat显示的内容:

netstat -tulpn | grep 29406
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 10.137.2.166:29406      0.0.0.0:*               LISTEN      -               
udp        0      0 10.137.2.166:29406      0.0.0.0:*                           -   

And this is whats in /etc/hosts这是/etc/hosts

cat /etc/hosts
127.0.0.1 localhost

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

I've downloaded jmxterm on the server to try and connect to it, and noticed an interesting behavior.我已经在服务器上下载了jmxterm以尝试连接到它,并注意到一个有趣的行为。 When I try using localhost to connect to the port, I get this:当我尝试使用localhost连接到端口时,我得到了这个:

#RuntimeIOException: Runtime IO exception: Failed to retrieve RMIServer stub: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused (Connection refused)]

When I use its own IP address, it then seems to work:当我使用它自己的 IP 地址时,它似乎可以工作:

$>open 10.137.2.166:29406
#Connection to 10.137.2.166:29406 is opened
$>

Curious to understand why localhost doesn't work when I'm running this on the server itself...很想知道为什么当我在服务器上运行它时 localhost 不起作用......

The only way I've gotten jconsole (running on my laptop) to connect to it is by using an ssh tunnel like this:我让jconsole (在我的笔记本电脑上运行)连接到它的唯一方法是使用这样的 ssh 隧道:

ssh -Nf -D 7777 10.137.2.166
jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=7777 service:jmx:rmi:///jndi/rmi://10.137.2.166:29406/jmxrmi -J-DsocksNonProxyHosts=

I feel like I should be able to connect to it without creating a tunnel but unsure why I can't.我觉得我应该能够在不创建隧道的情况下连接到它,但不确定为什么我不能。 If I run telnet locally from my laptop to the host, the connection does seem to open...如果我从笔记本电脑本地运行 telnet 到主机,连接似乎打开了......

telnet 10.137.2.166 29406
Trying 10.137.2.166...
Connected to 10.137.2.166.
Escape character is '^]'.

To successful JMX handshake成功的 JMX 握手

  1. the jmx server should be available by a host name outside (should also be declared on server jvm via java.rmi.server.hostname system property) jmx 服务器应该可以通过外部的主机名使用(也应该通过java.rmi.server.hostname系统属性在服务器 jvm 上声明)

  2. in addition to one open port (can be explicitly declared via com.sun.management.jmxremote.rmi.port jvm property) the jmx server chooses random another that's used for new jmx connection.除了一个开放端口(可以通过com.sun.management.jmxremote.rmi.port jvm 属性明确声明)之外,jmx 服务器会随机选择另一个用于新 jmx 连接的端口。 It's quite problematic because you can't foresee particular port in order to exclude it from server's firewall restrictions, so the tunneling is necessary.这是相当有问题的,因为您无法预见特定端口以将其排除在服务器的防火墙限制之外,因此隧道是必要的。

Server listened at only 10.137.2.166.服务器仅在 10.137.2.166 侦听。 When you trying to create new socket with localhost domain, your application tying to establish 127.0.0.1 adress but your application not listening at this ip.当您尝试使用 localhost 域创建新套接字时,您的应用程序将建立 127.0.0.1 地址,但您的应用程序并未侦听此 IP。

If you want to connect with localhost domain you have few options for solving.如果你想连接 localhost 域,你有几个解决方案。

  1. Change your server configuration to listen on 127.0.0.1 and 10.137.2.166 at same time.更改您的服务器配置以同时侦听 127.0.0.1 和 10.137.2.166。
  2. Change your server configuration to listen on 0.0.0.0 .更改您的服务器配置以侦听0.0.0.0

    Listening at 0.0.0.0 its not recommended for security reasons .出于安全原因,不建议在0.0.0.0收听。

  3. Use iptables to forward port.使用 iptables 转发端口。 Requires root privileges.需要root权限。

sysctl net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp -i lo --dport 29406 -j DNAT --to-destination 10.137.2.166:29406
iptables -A FORWARD -p tcp -d 10.137.2.166 --dport 29406 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
  1. if you don't have root privileges you can use socat.如果您没有 root 权限,则可以使用 socat。
socat TCP-LISTEN:29406,fork,bind=127.0.0.1 TCP:10.137.2.166:29406

I only used jmx for visualvm connection and in this case they are two ports required to be available: com.sun.management.jmxremote.port=9010 com.sun.management.jmxremote.rmi.port=9011我只将 jmx 用于visualvm 连接,在这种情况下,它们是两个可用的端口:com.sun.management.jmxremote.port=9010 com.sun.management.jmxremote.rmi.port=9011

Also the java.rmi.server.hostname need to be set accordingly to the right network interface as the port will be bound only on that interface.此外, java.rmi.server.hostname需要相应地设置为正确的网络接口,因为端口将仅绑定在该接口上。

Once the ports are available from your client, you can use the jmx connection on the jmxremote.port port.一旦端口从您的客户端可用,您就可以在jmxremote.port端口上使用 jmx 连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM