连接到在Amazon EC2集群中运行的Java应用程序时遇到问题。
事实证明,问题是两个缺少设置的组合。第一个强制JRE选择ipv4而 不是 v6。这是必要的(我想),因为我们正尝试通过v4地址连接到它:
-Djava.net.preferIPv4Stack=true
真正的阻止因素是,JMX通过首先联系RMI端口来工作,该端口以 主机名
和端口作为响应,以供JMX客户端连接。如果没有其他设置,它将使用该框的本地IP,这是
10.X.X.X远程客户端无法路由到的虚拟地址。我们需要添加以下设置,它是服务器的
外部 主机名或IP-在这种情况下,它是服务器的弹性主机名。
-Djava.rmi.server.hostname=ec2-107-X-X-X.compute-1.amazonaws.com
如果要尝试自动执行EC2实例(以及为什么不这样做),诀窍在于如何在运行时查找此地址。为此,您需要在我们的应用程序启动脚本中添加以下内容:
# get our _external_ hostnameRMI_HOST=`wget -q -O - http://169.254.169.254/latest/meta-data/public-hostname`...java -server -Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=$RMI_HOST -jar foo.jar other parameters here > java.log 2>&1
上面命令中的神秘
169.254.169.254IP
wget提供了EC2实例可以请求有关其自身的信息。我很失望,其中 不
包含仅在经过身份验证的呼叫中可用的标签。
我最初使用的是extern
ipv4地址,但看起来好像JDK在启动时尝试与服务器端口建立连接。如果它使用外部IP,则这将减慢我们的应用程序启动时间,直到超时为止。public-
hostname在本地解析为10网络地址,在外部解析为public-ipv4。因此,该应用程序现在可以快速启动,并且JMX客户端仍然可以运行。呜呜!
希望这对其他人有帮助。今天花了我3个小时。
要强制您的JMX服务器在指定端口上启动服务器 和 RMI注册表,以便您可以在EC2安全组中阻止它们,请参阅以下答案:
如何关闭在特定端口上运行的rmiregistry?
编辑:
我们只是再次出现了这个问题。似乎Java JMX代码正在对主机名进行一些主机名查找,并使用它们尝试连接并验证JMX连接。
该问题似乎是要求框的本地主机名应解析为框的本地IP。举例来说,如果你
/etc/sysconfig/network有
HOSTNAME=server1.foobar.com那么如果你做一个DNS查找
server1.foobar.com,你应该得到的10-NET的虚拟地址。我们正在生成自己的
/etc/hosts文件,并且文件中缺少本地主机的主机名。这导致我们的应用程序在启动时暂停或根本不启动。
最后
简化JMX创建的一种方法是使用我的SimpleJMX包。



