阎老头 發表於 2023-2-1 10:17:00

linux服务器运行java项目, 监控查看内存、储存空间和cpu占用率

<pre><code class="language-textile">    服务器部署方式为tomcat中运行war包的方式, 有一次重新部署时候发现报异常堆栈溢出了.
想要定位到某个war包中通过学习整理出此篇文章以作记录笔记.
</code></pre>
<hr>
<p><mark><strong>关于远程调试</strong></mark>, 可以本地对线上代码debug调试, 可参考:</p>
<ul>
<li>Java远程调试(Remote Debugging)的那些事</li>
<li>Tomcat 开启远程调试</li>
</ul>
<hr>
<h3 id="0-如果奔着解决问题-见-arthas安装和简单应用">0. 如果奔着解决问题, 见: arthas安装和简单应用</h3>
<h3 id="1-关于内存过高的情况">1. 关于内存过高的情况</h3>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201094848093-1385949097.png" alt="image" loading="lazy"></p>
<p>不要看到<code>free</code>很少就很慌或者<code>used</code>很高, 就以为内存爆了. 其实不是, 是因为Linux内存管理技术 -- 虚拟内存</p>
<p>参考1: Linux下Java项目占用内存问题的分析</p>
<p>参考2: tomcat内存占用过高_jvm疯狂吞占内存,罪魁祸首是谁?</p>
<h3 id="2-顺便检查储存空间是否足够">2. 顺便检查储存空间是否足够</h3>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201094933066-1723085869.png" alt="image" loading="lazy"></p>
<p>如果存储数据或缓存的分区过大, 可以给分区扩容或清理缓存的方法.</p>
<p>/dev/vda[数字]过大情况下可参考一下连接:</p>
<ul>
<li>
<p>参考1: linux - /dev/vda1 is full but cannot find why - Stack Overflow</p>
</li>
<li>
<p>参考2: /dev/vda1 is mounted on / and using 94% of disk space</p>
</li>
<li>
<p>参考3: linux - 100% Usage /dev/dm-1 - Super User</p>
</li>
</ul>
<h3 id="3-内存堆栈信息---jarwar导出当时堆栈方式">3. 内存堆栈信息 - jar/war(导出当时堆栈方式)</h3>
<p>通过<code>jps</code>指令查看系统中运行的项目</p>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201101228935-647667866.png" alt="image" loading="lazy"></p>
<p>如果还有tomcat运行包, 会多一条<code> Bootstrap</code>数据</p>
<p>(服务器测试时没有jar包的名称, 可能Bootstrap名称也会不同)</p>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201101257700-1115436587.png" alt="image" loading="lazy"></p>
<hr>
<p>生成线程堆栈转储文件(war和jar都是使用java执行的, 都是查看进程id)</p>
<ul>
<li>
<p>使用<code>jmap -dump:format=b,file=wanfile.dump 21445</code>导出堆栈文件, 并且下载到本地. jmap生成的堆转储文件包含了Java堆中的所有对象的详细信息, 所以会大一点, 对比jcmd和jstack.</p>
</li>
<li>
<p>相关的指令还有<code>jcmd</code>: jcmd &lt;进程ID&gt; GC.heap_dump &lt;文件路径&gt;<br>
jcmd是JDK中的一个命令行工具,用于与Java进程进行交互并执行各种操作。它提供了一系列的命令,可以用于监控、诊断和调试Java应用程序。以下是jcmd的一些常用功能:</p>
<ul>
<li>
<p>VM相关操作:jcmd可以执行与Java虚拟机(JVM)相关的操作,如生成堆转储文件、强制执行垃圾收集、打印系统属性等。例如,您可以使用<code>jcmd &lt;进程ID&gt; GC.run</code>命令来强制执行垃圾收集操作。</p>
</li>
<li>
<p>线程相关操作:jcmd可以查看和管理Java进程中的线程。您可以使用<code>jcmd &lt;进程ID&gt; Thread.print</code>命令来打印线程的详细信息,包括线程ID、状态、堆栈跟踪等。还可以使用<code>jcmd &lt;进程ID&gt; Thread.dump</code>命令生成线程的堆栈转储文件。</p>
</li>
<li>
<p>类相关操作:jcmd可以执行与Java类相关的操作,如打印加载的类信息、触发类卸载等。例如,您可以使用<code>jcmd &lt;进程ID&gt; VM.class_stats</code>命令来打印加载的类的统计信息。</p>
</li>
<li>
<p>JMX相关操作:jcmd可以与Java管理扩展(JMX)进行交互,执行与MBeans相关的操作。您可以使用<code>jcmd &lt;进程ID&gt; ManagementAgent.start</code>命令启动JMX代理,以便远程管理和监控Java进程。</p>
</li>
<li>
<p>JVM统计信息:jcmd可以获取Java进程的各种统计信息,如线程、类加载、垃圾收集、编译器等的统计数据。您可以使用<code>jcmd &lt;进程ID&gt; VM.native_memory</code>命令来查看本地内存使用情况。</p>
</li>
<li>
<p>其余的请参考相关的JDK文档或运行<code>jcmd -help</code>命令来获取帮助信息。</p>
</li>
</ul>
</li>
<li>
<p>另外还可以使用jstack生成线程快照, 功能与jcmd类似(jstack较旧, jcmd新一点): <code>jstack 21445 &gt; 21445.log</code><br>
也可以打印在命令行, 或者使用<code> | grep 'at com.'</code>来过滤.<br>
参考: tomcat服务器cpu占用率居高不下<br>
参考: 线上问题排查命令<br>
参考: Tomcat进程占用CPU过高怎么办?</p>
</li>
</ul>
<hr>
<h3 id="4-分析软件">4. 分析软件</h3>
<ul>
<li>网站: FastThread将堆栈信息上传网站可以分析出一些出一些信息参考, 另外推荐软件arthas, 可以在服务器上很方便的进行监控诊断.</li>
<li>jvisual<br>
可以在线监控,<br>
使用<code>jvisualvm.exe</code> 打开, 与<code>java.exe</code>和<code>javac.exe</code>都在同目录<code>%JSAVA_HOME/bin%</code>下</li>
</ul>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201101323706-613335675.png" alt="image" loading="lazy"></p>
<p>点击<code>显示系统属性</code>, 可以查看到当前的jar包运行的参数, 包括当前jar包的名称.</p>
<p>之后我也将<code>Bootstrap</code>也下载了下来</p>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201101334325-909721111.png" alt="image" loading="lazy"></p>
<p><code>类</code>: 可以查看堆栈中的类信息, 主要查看自己定义的类的实例数和<code>ArrayList</code>是否过高</p>
<p><em>注: java11包括java11之后的版本不再提供<code>jvisualvm.exe</code>, 有需要的话可以在VisualVM: Download 下载.</em></p>
<p>参考1: linux环境下导出项目的堆栈dump文件</p>
<p>参考2: jvisualvm.exe使用介绍</p>
<hr>
<ul>
<li>memory analyzer</li>
</ul>
<p>如果常用jdk(系统变量path中配置的)是java8的话, 由于此工具要求jdk版本是java11+, 所以需要手动配置java11, 在<code>MemoryAnalyzer.exe</code>同目录下的<code>MemoryAnalyzer.ini</code>配置文件中最前面添加<code>-vm path</code>:</p>
<pre><code class="language-textile">-vm
C:\Program\Java\java-11\bin\javaw.exe
-startup
plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.2.400.v20211117-0650
-vmargs
-Xmx1024m
</code></pre>
<p>参考1: 官网下载地址</p>
<p>参考2: MemoryAnalyzer指定JDK版本</p>
<p>参考3: Memory Analyzer基本使用</p>
<p>参考4: 一文让你理解什么是shallow heap及retained heap</p>
<h3 id="5-在线监控">5. 在线监控</h3>
<p>tomcat中的各个war的运行情况暂时无法分开查看</p>
<ul>
<li>
<p>目标<code>tomcat</code>的<code>bin</code>目录下的<code>catalina.sh</code>文件内添加以下内容并重启tomcat<br>
使用jar运行的话, 也是添加以下参数</p>
<pre><code class="language-shell"># 1.之前是写到一行, 但是启动有问题, 后面拆开多行成功
# 2.hostname填写ip或者域名
# 3.port使用的是与tomcat或docker相同的端口(尝试使用不同的未能成功, 于参考4中发现)
# 4.authenticate代表是否需要鉴权
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote=true"
CATALINA_OPTS="$CATALINA_OPTS -Djava.rmi.server.hostname="
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.port=80"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
</code></pre>
</li>
<li>
<p>打开软件<code>visualvm</code>, 右键打开<code>Add Remote Host...</code></p>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201101047588-1369147978.png" alt="image" loading="lazy"></p>
<ul>
<li>
<p>输入<code>hostname</code>, 目标服务器的ip或域名, 点击<code>OK</code></p>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201101101425-173721350.png" alt="image" loading="lazy"></p>
</li>
<li>
<p>右键新添加的远程主机, 点击<code>Add JMX Connection...</code></p>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201101111922-1661605.png" alt="image" loading="lazy"></p>
</li>
<li>
<p>填写上接口, 同服务器配置中的<code>port</code></p>
</li>
<li>
<p>如果配置上<code>jmxremote.authenticate=true</code>, 需要填写上配置的用户名和密码</p>
</li>
<li>
<p>勾选上不需要SSL连接, 同配置中的<code>jmxremote.ssl=false</code></p>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201101133056-1062543862.png" alt="image" loading="lazy"></p>
</li>
<li>
<p>点击<code>OK</code>后其下会出现下图所示</p>
<p><img src="https://img2023.cnblogs.com/blog/994192/202302/994192-20230201101146974-174663366.png" alt="image" loading="lazy"></p>
</li>
<li>
<p>双击上图箭头所指位置, 右侧窗口中可看到具体内容</p>
</li>
<li>
<p><code>visualvm</code>功能可在官网上的<code>Features</code>和<code>Documentation</code>进行查阅.</p>
</li>
</ul>
</li>
<li>
<p>JDK Mission Control(jmc)</p>
<ul>
<li>使用方法与上面工具类似, 都需要配置远程连接</li>
<li>下载: JDK Mission Control (JMC) 8 Downloads</li>
</ul>
</li>
<li>
<p>jconsole</p>
<ul>
<li>与jvisualvm一样在bin目录下</li>
<li>连接方式也与jvisual相同, 比较简陋</li>
</ul>
</li>
</ul>
<hr>
<p>参考1: jvisualvm.exe使用</p>
<p>参考2: VisualVM详解</p>
<p>参考3: jvisualvm 监控 tomcat 实例(qbit)</p>
<p>参考4: Has anyone ever got a remote JMX JConsole to work?</p>
<p>参考5: jvisualvm之jmx远程连接</p>
<p>参考6: java jmx jboss_通过JMX远程监控</p><br><br>
来源:https://www.cnblogs.com/Ddlm2wxm/p/17081722.html
頁: [1]
查看完整版本: linux服务器运行java项目, 监控查看内存、储存空间和cpu占用率