27

在开启 jpda 启动 tomcat 后,在我的公司,我可以在 eclipse 中远程调试一堆 Web 应用程序。由于多种原因,我现在需要从公司防火墙外部开发和远程调试这些相同的 web 应用程序,并且我只能通过端口 22 上的 ssh 访问该服务器。

我将最需要的端口(svn、nexus、tomcat 本身、从服务器或通过服务器)隧道传输到 localhost,这些服务工作正常,但我无法以任何方式启动 eclipse 调试器;从我第二次尝试开始,我收到“等待数据包 XXX 时连接超时”或“连接被拒绝”。使用服务器上的 nmap 检查,它会在第一次连接尝试之前报告端口打开,然后它会关闭。我在 catalina.out 中没有得到有趣的输出日志

我用来启动隧道的命令是:

ssh -L 8000:localhost:8000 user@mycompany.com

iptables 在服务器和本地机器上都暂时停止以进行测试。

我错过了什么吗?我需要将其他端口转发到本地主机吗?还是以某种方式涉及名称解析?

编辑

在 eclipse 连接尝试之前打开端口:

root@lnxulisse:/opt/apache-tomcat-6.0.32/bin# lsof -p 2147  -n |grep TCP
java    2147 root    4u  IPv4 640850      0t0     TCP *:8000 (LISTEN)
java    2147 root   38u  IPv6 640859      0t0     TCP *:http-alt (LISTEN)
java    2147 root   40u  IPv6 640865      0t0     TCP *:https (LISTEN)
java    2147 root   46u  IPv6 640908      0t0     TCP 127.0.0.1:18005 (LISTEN)
java    2147 root   48r  IPv6 642625      0t0     TCP 172.24.0.82:48347->172.24.0.82:mysql (ESTABLISHED)
java    2147 root  181u  IPv6 640891      0t0     TCP 172.24.0.82:60353->172.24.0.82:mysql (ESTABLISHED)

之后:

java    2147 root    4u  IPv6 642769      0t0     TCP 172.24.0.82:48956->172.24.0.82:mysql (ESTABLISHED)
java    2147 root    5u  IPv4 640851      0t0     TCP 127.0.0.1:8000->127.0.0.1:34193 (ESTABLISHED)
java    2147 root   38u  IPv6 640859      0t0     TCP *:http-alt (LISTEN)
java    2147 root   40u  IPv6 640865      0t0     TCP *:https (LISTEN)
java    2147 root   46u  IPv6 640908      0t0     TCP 127.0.0.1:18005 (LISTEN)
java    2147 root  181u  IPv6 640891      0t0     TCP 172.24.0.82:60353->172.24.0.82:mysql (ESTABLISHED)

返回的确切日食错误是:

Exception occurred during launch
Failed to connect to remote JVM. Connection timed out.
Timeout occurred while waiting for packet 204.

(每次尝试的数据包编号都不同)。

workspace/.metadata/.log我得到:

!ENTRY org.eclipse.osgi 2 0 2011-07-17 18:43:53.024
!MESSAGE While loading class "org.eclipse.core.net.proxy.IProxyService", thread "Thread[main,6,main]" timed out waiting (5000ms) for thread "Thread[Thread-6,5,main]" to finish starting bundle "org.eclipse.core.net_1.2.1.r35x_20090812-1200 [232]". To avoid deadlock, thread "Thread[main,6,main]" is proceeding but "org.eclipse.core.net.proxy.IProxyService" may not be fully initialized.
!STACK 0
org.osgi.framework.BundleException: State change in progress for bundle "reference:file:plugins/org.eclipse.core.net_1.2.1.r35x_20090812-1200.jar" by thread "Thread-6".
        at org.eclipse.osgi.framework.internal.core.AbstractBundle.beginStateChange(AbstractBundle.java:1073)
        at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:278)
[...]

!ENTRY org.eclipse.ui.ide 4 4 2011-07-17 18:43:53.028
!MESSAGE Proxy service could not be found.

eclipse 配置为直接连接互联网。

编辑 2

我认为解决方案可能在这里:

http://blog.cantremember.com/debugging-with-jconsole-jmx-ssh-tunnels/

但我在理解他的 JNDI/RMI 设置以及在多大程度上适用于我的配置时遇到了一些麻烦。

编辑 3

这是对那些回答“使用<lan|local ip address>而不是<localhost>”的人的澄清

  • 电脑A:我在公司的工作站
  • 电脑B:我家的工作站
  • 计算机C:运行tomcat的服务器

B 和 C 在同一网络基础设施中的两个不同子网络中;只允许从外部连接到 C 的端口 22(并且有点“代理”,我不知道网络内部情况)。

A 是“外部”(我的 dsl 连接与动态 IP 地址)。

Debugging on C from B via ssh tunnel -> works
Debugging on C from A via ssh tunnel -> connection timed out while waiting for packet XXX
4

5 回答 5

10

本文建议远程 Java 虚拟机 (JVM) 在调试模式下侦听的默认端口是 1044。您也应该隧道运行远程 JVM 的端口。


更一般地,您可以运行 wireshark/tcpdump 来查看在启动调试器时尝试连接到哪些端口。


编辑

我会尝试更多的事情:

  • 检查远程主机(例如,ps auxwww如果它是 Linux)带有哪些参数(查找后面的内容-Xrunjdwplsof -p PID_OF_JVM_TO_BE_DEBUGGED它侦听的 TCP 端口(查找输出中带有TCPLISTEN的行lsof
  • 确保远程主机上的 JVM 侦听lo接口,而不是网络接口(这是您localhost-Lssh 选项中指定的)。
  • 是否在您启动 eclipse 的机器上手动启动调试器jdb -attach localhost:8000?(您也可以在远程主机上尝试此操作,以确保调试器在端口 8000 上运行)
  • 确保 eclipse 尝试连接localhost(当没有在第一个 8000 之前指定绑定地址时使用-L选项 ssh 在lo接口上侦听)
于 2011-07-16T18:40:30.117 回答
10

我在进行远程调试时经常遇到这个问题。我不知道这个问题的确切原因,但我使用了以下解决方案,也许它也适合你:

代替

ssh -L 8000:localhost:8000 user@remotehost

用来

ssh -L 8000:remotehost:8000 user@remotehost

用于创建 SSH 隧道(请注意第二个示例中端口号之间的 remotehost 而不是 localhost)。除了远程主机的名称,您还可以使用远程主机的普通 IP 地址(不是环回地址 127.0.0.1,而是真正的本地网络 IP 地址)。

希望它有所帮助,祝你好运!

于 2012-11-25T15:58:50.780 回答
8

假设远程 Tomcat 实例以类似的方式启动-Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n,请尝试以下命令:

ssh -L 8000:0.0.0.0:8000 user@mycompany.com -N

在我的 Mac 上,我在本地尝试了一个 Tomcat 实例以 启动,并尝试在 Eclipse 中连接端口 10701,我一直看到“无法连接到远程 VM com.sun.jdi.connect.spi.ClosedConnectionException”。通过将隧道命令更改为,Eclipse 能够附加。ssh -L 10701:localhost:10700 user@localhost -N-Xrunjdwp:transport=dt_socket,server=y,address=10700,suspend=nssh -L 10701:0.0.0.0:10700 user@localhost -N

于 2012-11-18T23:57:47.283 回答
3

您能否给出 -Xrunjdwp 参数的确切参数?

您是否也尝试过不同的调试方法(server=y/n,suspend=y/n)?

也许反转连接(让 tomcat 连接到调试器而不是让调试器连接到 tomcat)可能会有所帮助。

于 2012-11-15T07:39:46.963 回答
3

好吧,我在很长一段时间后回答自己;在我的具体情况下,解决方案是将 eclipse JVM 置于监听模式:

Connection Type: "Standard (Socket Listen)"

并反转隧道的方向:

ssh -L 8001:localhost:8001 user@work   (run on server (S), "localhost" is W)
ssh -R 8001:localhost:8001 user@work   (run at home (H), "localhost" is W)

一些解释:在问题中,我的情况是:

  H  -------------------> S     not working  ( ssh -L 8001:S:8001 user@S  from H)
  H           W  -------> S     working      ( ssh -L 8001:S:8001 user@S  from W)
 home        work      server

像这样倒车时:

  H  <------- W           S     ssh -R 8001:localhost:8001 user@W  (from H)
  H           W  <------- S     ssh -L 8001:localhost:8001 user@W  (from S)
 home        work      server

成功了。换句话说,任何写在 S:8001 上的东西都会被转发到 W:8001,而任何写到 W:8001 的东西都会被转发到 H:8001,我的 eclipse JVM 正在那里监听。

S 上的 tomcat JVM 应该以 server=n 启动,参数:

-agentlib:jdwp=transport=dt_socket,server=n,suspend=n,address=8001
于 2013-09-16T14:26:16.067 回答