【问题标题】:Unable to use JVisualVM profiling for Tomcat7 running as a service on Windows7无法对在 Windows7 上作为服务运行的 Tomcat7 使用 JVisualVM 分析
【发布时间】:2013-01-12 12:22:59
【问题描述】:

我正在尝试使用本地运行的 JVisualVM(JDK 1.7.0 - 06、64 位)将在 Apache Tomcat (7.0.34) 中运行的 Servlet 作为 Windows 7(64 位)上的服务进行分析。

最初,由于不同的“java.io.tmp”属性错误/功能,我遇到了 Tomcat 未显示在本地应用程序列表中的问题,但按照本论坛的几篇帖子中的建议解决了这个问题。

然而,尽管 Tomcat 进程现在在本地应用程序列表中显示为“本地应用程序”,但当我打开该进程时,没有监视器、线程、采样器或配置文件的选项卡 - 只有 JVM 参数的概览选项卡和系统属性子选项卡显示可怕的“此 jvm 不支持”消息。

我已经仔细检查了以下项目:

  • 通过查看 JVisualVM 中的 JVM 属性(使用 Tomcat 的 JMX 连接),Tomcat 和 JVisualVM 都在运行相同版本的 Java
  • 通过查看 JVisualVM 中的系统属性(再次使用 Tomcat 的 JMX 连接)并查看实际的 TMP/TEMP 目录并确认 PID,Tomcat 和 JVisualVM 具有相同的“java.io.tmp”路径两者的文件都存在
  • 文件系统是 NTFS
  • Windows 用户的名称中没有下划线(注意:用户的名称中确实有句点,因为我们使用的是“firstname.lastname”形式的网络登录,但是我在查看其他 Java 时没有问题JVisualVM 中的应用程序,所以不要认为这是一个问题)
  • 通过查看任务管理器中的进程,Tomcat 和 JVisualVM 都作为同一个 Windows 用户执行

最后几点:

  • 我需要Profile Servlet,所以使用 JMX 是不够的
  • 我能够在 Windows XP 机器上进行分析(Java 7、Tomcat 7 即服务),所以看起来是 Windows 7 / 64 位的东西?

如果有人已经解决了这个问题,显然这个解决方案将不胜感激。然而,如果其他人正在运行相同的配置 - Windows 7 64 位、Java 7 64 位、Tomcat 7 作为服务运行 - 成功,这将很有用。

更新:我没有作为服务运行,而是使用批处理文件运行 Tomcat,并且一切正常:作为服务运行有什么意义?

【问题讨论】:

  • 只是让你知道你没有疯,我在其他 servlet 容器上也遇到过同样的问题。我通常启动 Sysinternals 进程资源管理器,查看“命令行”列(默认的 Win 进程资源管理器上限为 255 个字符),从命令提示符执行,然后附加 VisualVM。
  • 您的 Tomcat 服务以哪个 Windows 用户身份运行?这可以使一切变得不同。尝试以与运行 Tomcat 服务的用户完全相同的用户身份运行 VisualVM。

标签: windows tomcat profiling visualvm jvisualvm


【解决方案1】:

正如我之前的评论中已经暗示的那样。我想简单的答案是不可能。为了实现jconsole/jvisualvm与被监控进程之间的通信,Java使用了内存映射文件。最后归结为某个 Windows API 调用由于 Windows Vista 中添加的“Windows 服务强化”[1] 功能而失败,当然,Windows 7 及更高版本中也存在该功能。

调用失败的是函数 OpenFileMapping,如 perfMemory_windows.cpp 第 1402 行 [2] 中所示。在我的实验中,该方法是使用“hsperfdata_[username]_[process id]”形式的参数调用的。正如微软对服务强化(参见 [3])引入的差异的进一步详细说明,如果不使用名称前缀,通信将不起作用:“如果用户应用程序 [...] 通过创建或打开来与服务同步带有 Local\ 前缀(或无前缀,默认为 Local)的对象,应用程序不再按预期工作。”

如果有人想亲自看看。您可以使用 Windows 调试工具中包含的 Logger 工具 [4] 来跟踪 API 调用。

此外,Sysinternals Process Explorer 非常方便,因为它通过“查找句柄或 DLL...”功能显示用于内存映射文件的全名。只需搜索包含“hsperf”的句柄。

附带说明:删除或以其他方式弄乱包含 hsperf 数据的临时目录的解决方法归结为要监视的进程和监视进程使用的用户名的大小写需要一致.但是,除了更改临时目录之外,您还可以轻松更改监视进程使用的 USERNAME 环境变量。您还可以在 perfMemory_windows.cpp 第 272 行 [2] 中查看它是如何使用的。

[1]http://technet.microsoft.com/en-us/library/cc507844.aspx#EHF

[2]http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/file/5dce25362b8a/src/os/windows/vm/perfMemory_windows.cpp

[3]http://msdn.microsoft.com/en-us/windows/hardware/gg463353.aspx

[4]http://msdn.microsoft.com/en-us/library/windows/hardware/ff560123(v=vs.85).aspx

【讨论】:

    【解决方案2】:

    你几乎做到了“我没有作为服务运行,而是使用批处理文件运行 Tomcat,并且一切正常:作为服务运行是什么意思”现在剩下的唯一步骤是将 JVisualVM 作为服务运行 :)

    参考这个

    https://blogs.oracle.com/nbprofiler/entry/monitoring_java_processes_running_as

    由于只能分析在与 VisualVM 相同的用户下运行的 Java 进程,因此分析 Windows 服务(默认情况下在系统帐户下运行)的唯一方法是将 VisualVM 本身作为 Windows 服务启动。请注意,由于安全限制默认情况下会阻止服务显示任何 UI,因此此方法在 Windows Vista 上不起作用。

    另一个选项是运行 Run CMD.EXE as Local System ,请参阅下文。

    http://vicevoice.blogspot.in/2009/09/vaas-visualvm-as-service.html

    【讨论】:

    • (& JoshDM) - 感谢回复,但我确实确保服务以我登录的用户身份运行(请参阅“双重检查项目”的最后一个点在原始帖子中;-)。另请注意,我能够让事情在 XP 上运行。我在帖子中没有提到的一点是,我还尝试以管理员身份运行 VisualVM - 那里也没有乐趣。但是,我将尝试将 VisualVM 作为服务运行并让您知道。再次感谢
    • 似乎将 cmd 作为本地系统运行(或至少如该链接中的链接所述!)在 Windows 8 上不起作用。原始文章来自 2004 年,我想从那时起事情已经发生了变化.它看起来很相似,除了我收到关于 type= interact 被弃用的警告
    【解决方案3】:

    你不能只通过网络连接,即启动 JVM

     java 
      -Dcom.sun.management.jmxremote
      -Dcom.sun.management.jmxremote.port=1234 
      -Dcom.sun.management.jmxremote.local.only=false 
      -Dcom.sun.management.jmxremote.authenticate=false 
      -Dcom.sun.management.jmxremote.ssl=false 
      -jar my.jar`
    

    并在工具中创建到 localhost:1234 的网络连接

    【讨论】:

      【解决方案4】:

      如果有人在 Windows 7 上有解决方案,我也很好奇。如前所述,将 VisualVM 作为服务运行的技巧在 Vista 上不起作用,我假设相同的安全功能会阻止它运行赢 7。

      我唯一的解决方案是将您的应用服务器 (Tomcat) 设置为服务,这样如果服务器重新启动,它就会启动并可用。然后手动停止服务并从命令行启动您的应用服务器 (Tomcat) 并与 VisualVM 连接。只要服务器没有重启,你就可以得到很好的监控。

      【讨论】:

      • 作为补充说明,为什么在 Windows Vista 及更高版本中将 jconsole/jvisualvm 与 Windows 服务一起使用变得更加困难。这是由于添加了一个名为“Windows 服务强化”[1] 的新“功能”。我认为这与会话隔离机制有关,因为 jconsole/jvisualvm 依赖于需要跨越会话边界的本地 IPC 机制(共享内存映射文件或命名管道)。 [1]technet.microsoft.com/en-us/library/cc507844.aspx#EHF
      猜你喜欢
      • 1970-01-01
      • 2013-02-14
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多