我尝试了几种选择
a。 cf java thread-dump myapp -i0
(那里只有1个实例,所以为0)回应无济于事。myapp的日志显示2019-12-13T14:52:41.15 + 0800 [SSH / 0] OUT成功通过10.x.x.x:35764进行远程访问2019-12-13T14:52:41.84 + 0800 [SSH / 0] OUT远程访问已结束,适用于10.x.x.x:35764
b。我做了cf ssh myapp
/ home / vcap / app / .java-buildpack / open_jdk_jre / bin /没有jstack并且jmap命令也不起作用/home/vcap/app/.java-buildpack/open_jdk_jre/bin/具有以下组件
java orbd servertool java-buildpack-memory-calculator-3.13.0_RELEASE pack200 tnameservjjs policytool unpack200jvmkill-1.16.0_RELEASE rmidkeytool rmiregistry
问题是->如何获取java threaddump?
我相信最简单的选择是运行cf logs
来查看您的应用日志。然后在第二个终端中,将cf ssh
移至应用程序并运行ps aux
,然后查找Java进程的进程ID。然后运行kill -3 <pid>
。您的Java进程将捕获此信号并发出线程转储。它将进入STDOUT,它方便地进入您应用的日志流,因此应显示在第一个终端中。
最糟糕的部分是cf logs
将在每行的开头插入一些其他文本,这使得很难将线程转储加载到工具中。通常,您可以使用cut
或awk
删除它,也可以将cf logs
重定向到文件,使用文本编辑器打开并查找/替换前导文本。
除了您还有其他选择:
如果您使用的是Spring,请启用Spring Boot执行器。然后,您可以使用/actuator/threaddump
端点生成并下载线程转储(请注意,此格式为JSON,而不是标准格式)
使用APM工具或分析器,例如NewRelic,AppDynamics,Dynatrace或YourKit。 Java buildpack对它们提供了很好的支持,并且大多数都可以使用。
使用JMX。使用Java buildpack启用它很容易,只需将env变量JBP_CONFIG_JMX
设置为'{enabled: true}'
并重新启动应用程序即可。启用后,您可以使用cf ssh -N -T -L 5000:localhost:5000 <APP_NAME>
打开隧道。然后打开jvisualvm
,与“ localhost:5000”建立新的“本地” JMX连接并进行连接。单击“线程”选项卡,然后单击“线程转储”按钮。它穿过隧道时可能会有点慢,但是要花几秒钟才能完成,您应该有一个线程转储。
[Cloud Foundry无法使用的是jstack
和jcmd
。在撰写本文时,Java buildpack安装了JRE,并且这些工具不再随OpenJDK JRE一起提供,并且出于法律原因不能与之捆绑在一起。如果您愿意,可以从JDK到工具容器scp
这些工具和所需的共享库,然后运行它们,但这是很多工作,而且并不有趣。我对cf java
插件不是很熟悉,但是我怀疑它会尝试使用这些工具,这些工具过去一直可用,并且不再存在。
希望有帮助!
您应该能够使用kill -3 <PID>
获取ThreadDumps,并在堆分析器中将其打开,例如eclipse memory analyzer (MAT),然后选择Thread Stacks