首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Docker on GCE中附加VisualVM或JConsole到Java

在Docker on GCE中附加VisualVM或JConsole到Java
EN

Stack Overflow用户
提问于 2017-08-02 06:57:01
回答 1查看 2.4K关注 0票数 3

我正在尝试让一些CPU采样在远程Java-in-Docker进程上工作。

我已经查看了这里的相关问题,并尝试了所有方法,但都没有用,所以我在这里发布了我的设置。

我有一个Java进程(openjdk-8)在Google Compute Engine (GCE)实例上的Docker容器中运行。GCE实例和容器都在运行Debian-9。我希望将VisualVM或JConsole附加到我的Java进程。

我能够在本地运行我的docker容器,并使用localhost:9010连接到visualvm和jconsole。

我在VM启动脚本中使用以下命令启动容器:

代码语言:javascript
复制
docker run -d -p 9010:9010 <my container>

Dockerfile还具有:

代码语言:javascript
复制
EXPOSE 9010

由Dockerfile CMD启动的Java进程具有以下相关参数:

代码语言:javascript
复制
"-Dcom.sun.management.jmxremote", \
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \
"-Dcom.sun.management.jmxremote.local.only=false", \
"-Dcom.sun.management.jmxremote.authenticate=false", \
"-Dcom.sun.management.jmxremote.ssl=false", \

我已经在我的gcloud防火墙中打开了端口9010,使用:

代码语言:javascript
复制
gcloud compute firewall-rules create jmx-port --allow=tcp:9010,udp:9010

我已经向netcat确认该端口已打开,并且可以建立到该端口的TCP连接。

我从同一个Docker容器打开了其他端口,客户端成功连接到这些端口。它们以相同的方式暴露并映射到主机端口(-p端口:端口),并以相同的方式在防火墙中打开。

我正在传递GCE实例的外部IP地址。例如,如果我这样做:

代码语言:javascript
复制
gcloud compute instances list

它告诉我:

代码语言:javascript
复制
NAME            ZONE           MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
my-server-b23j  us-central1-d  n1-standard-1               10.240.0.2   108.357.213.99   RUNNING

然后我将使用参数:

代码语言:javascript
复制
108.357.213.99:9010

作为远程jmx连接host:port对。

VisualVM和JConsole都告诉我他们无法连接到远程JMX服务。在这两种情况下,我都拒绝了安全连接,然后他们会说:

代码语言:javascript
复制
Cannot connect to 108.357.213.99:9010 using
service:jmx:rmi:////jndi/rmi://108.357.213.99:9010/jmxrmi

无奈之下,我添加了一条防火墙规则,在所有端口0-65535上启用TCP/UDP连接,但这并没有什么不同--它们仍然无法连接。

我读到过JMX-RMI开放匿名端口,并且您可以(至少部分地?)通过同时指定以下两项来禁用此行为:

代码语言:javascript
复制
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \

然而,在我的情况下,它并不起作用。

我已经阅读了here,您需要指定rmi服务器主机名:

代码语言:javascript
复制
-Djava.rmi.server.hostname='192.168.99.100'

但是我的服务器IP是短暂的--它是由Google Compute Engine在我创建实例时分配的,所以我不能将它与其他Java参数一起硬连接到Dockerfile中。

我是否必须获得静态IP地址才能正常工作?

EN

回答 1

Stack Overflow用户

发布于 2017-08-02 16:52:38

一种可能的解决方案是ssh到您的GCE机器和端口转发端口9010。可以从本地控制台使用以下命令完成此操作:

代码语言:javascript
复制
gcloud compute ssh name-of-your-gce-engine -- -L 9010:localhost:9010

然后在jconsolejvisualvm中连接到localhost:9010。在这里使用localhost意味着jconsole/jvisualvm将连接到您的本地计算机,这个连接由ssh隧道传输到您的GCE引擎,然后连接到-L参数中定义的主机和端口,该参数是localhost:9010,但是从GCE- engine的角度来看。这意味着你将在你的应用程序中结束。

在启动程序之前,您仍然需要设置rmi服务器名称,但您必须使用

代码语言:javascript
复制
-Djava.rmi.server.hostname='localhost'

因此RMI将告诉jconsole/jvisualvm使用本地主机,然后这将解析到本地隧道端点。当然,你仍然需要这些:

代码语言:javascript
复制
"-Dcom.sun.management.jmxremote", \
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \
"-Dcom.sun.management.jmxremote.local.only=false", \
"-Dcom.sun.management.jmxremote.authenticate=false", \
"-Dcom.sun.management.jmxremote.ssl=false", \
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45448881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档