我们最终采用的解决方案实际上并未使用 Jolokia 或 Hawt.io。
我们最终使用了Jconsole。
查看ActiveMQ队列时,如果你在队列中使用了java序列化的对象,数据的可读性不是很好,但是如果你将你的对象序列化为json,就很容易看到队列中有什么排队。
不过,仔细阅读这些说明非常重要。
这些说明讨论了SSH Tunneling,很容易把事情搞砸,而且当出现问题时也没有很好的日志消息。
远程调试
出于安全原因,我们已关闭远程虚拟机上所有打开的调试端口。
要让远程调试工作,我们需要使用SSH Tunneling 访问远程虚拟机调试端口。
远程应用程序设置
您要远程调试的应用程序必须启用 JPDA 传输连接器。
在 Java 1.4 之后,要启用 JPDA Transport,请在启动 java 虚拟机时添加以下 vm 参数:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=<remote_port_number>
上面的属性很难描述,但上面介绍的效果很好。有关上述属性的更多信息,请访问Connection and Invocation Details 页面。
本地 IDE 设置
在 Intellij 中连接远程 java 虚拟机,打开“Run/Debug Configurations”窗口。
然后选择一个新的“远程”配置。
输入以下值:
| Debugger mode |
Attach to remote JVM |
| Host |
localhost |
| Port |
<local_port_number>* |
| Use module classpath |
<local_package>** |
- 应该是您将要启动的 ssh 隧道会话的本地端口号。建议 和 是相同的值。
** 这个值应该是你本地项目的名称。
SSH 隧道
要真正连接到远程调试端口,我们需要使用 SSH 隧道。
通过终端命令行运行以下命令:
$ ssh -L <local_port_number>:localhost:<remote_port_number> -f <username>@<remote_server_name> -N
例子:
$ ssh -L 10001:localhost:10001 -f <your_username>@<your.server.com> -N
此命令执行以下操作:
- 使用 启动 ssh 会话。
- 将您的 连接到远程计算机本地主机的 。在这种情况下,我们说连接到 机器的 localhost:10001。
在 Intellij IDE 中启动远程调试,然后您应该连接到远程 java 虚拟机。
资源
Intellij IDEA remotely debug java console program
Remote debug of a Java App using SSH tunneling (without opening server ports)
远程 JMX
我们使用 JMX 来查看 Spring Integration Kaha DB 队列。
远程应用程序设置
添加以下虚拟机参数:
-Dcom.sun.management.jmxremote.port=64250
-Dcom.sun.management.jmxremote.rmi.port=64250
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=127.0.0.1
jmxremote.port 和 jmxremote.rmi.port 可以是任意数字,并且它们可以是不同的值,如果在下面进行 ssh 隧道时它们是相同的值会很有帮助。
SSH 隧道
$ ssh -L 64250:localhost:64250 -f <your_username>@<your.server.com> -N
JConsole 设置
这是在一个新的终端窗口中完成的。
$ jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=64250 service:jmx:rmi:///jndi/rmi://127.0.0.1:64250/jmxrmi
资源
Why Java opens 3 ports when JMX is configured?
清理
要关闭上面的 ssh 进程:
$ lsof -i tcp | grep ^ssh
然后对进程id执行kill。
使用jps和jstack帮助调试
列出机器上运行的所有java进程:
$ sudo jps
列出正在运行的应用程序的线程:
$ sudo -u <process_owner> jstack <process_id>
例子:
$ sudo -u tomcat jstack <pid>