Tomcat 企业级运维实战系列(四):Tomcat 企业级监控

  • 一:监控工具
    • 1)概述
    • 2)流程
    • 3)部署
  • 二:监控命令
    • 1)`jps`
    • 2)`jstack`
    • 3)`jmap`
    • 4)`MAT` 工具分析
  • 三:监控脚本
  • 四:Java 系统负载与性能排查流程
    • 1)初步观察系统负载
    • 2)判断负载来源
    • 3)确定问题进程
    • 4)进一步分析
    • 5)问题解决与总结
  • 总结


🚀 Tomcat 系列文章导航
本系列系统讲解 Linux 环境下 Apache Tomcat 的部署、配置、管理与优化,并最终带你完成 企业级前后端分离项目上线。无论你是初学者还是想进阶的运维人员,这份路线图都能帮你快速构建完整的知识体系。

⚠️ 该系列所有涉及的软件包和项目都可以私信博主免费获取

  • 👉 第一部分:Tomcat 核心概念与基础部署
  • 👉 第二部分:Tomcat 系统化管理与应用部署
  • 👉 第三部分:Tomcat 配置解析与集群化部署
  • 👉 第四部分:Tomcat 企业级监控
  • 👉 第五部分:Tomcat 优化和安全加固
  • 👉 第六部分:综合项目实战:Java 前后端分离架构部署

一:监控工具

1)概述

  • 可通过 Zabbix / Grafana / Prometheus 等工具监控 Tomcat/Java。

  • 需要在 Tomcat 中开启 Java 远程监控功能(JMX Remote)

  • 也可在 Windows 安装 JDK,使用 jconsole / jvisualvm 工具远程连接 Tomcat 进行监控。

2)流程

  1. 在 Linux 修改 Tomcat 启动参数,开启 JMX 远程监控功能。

  2. 重启 Tomcat 使配置生效。

  3. 查看进程确认参数是否加载。

  4. 在 Windows 安装 JDK,并使用工具连接。

3)部署

  1. 修改 Tomcat 启动参数

    参数说明
    -Dcom.sun.management.jmxremote开启远程监控功能
    -Dcom.sun.management.jmxremote.port=12345指定 JMX 端口
    -Dcom.sun.management.jmxremote.authenticate=false关闭认证
    -Dcom.sun.management.jmxremote.ssl=false关闭 SSL 加密
    -Djava.rmi.server.hostname=192.168.2.104绑定监听的 IP(通常填内网IP)
    [root@web01 ~]# vim /opt/module/tomcat-8.5.87/bin/catalina.sh
    

    ⚠️ 注意:Tomcat 8.5+ 中配置需用 \ 换行。

    CATALINA_OPTS="$CATALINA_OPTS \
    -Dcom.sun.management.jmxremote \
    -Dcom.sun.management.jmxremote.port=12345 \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Djava.rmi.server.hostname=192.168.2.104"
    

    在这里插入图片描述

  2. 启动 Tomcat

    [root@web01 ~]# systemctl start tomcat
    
  3. Window 安装 JDK

    配置环境变量:

    • JAVA_HOME=D:\...\jdk1.8.0_212
    • Path=%JAVA_HOME%\bin;
    C:\Users\86152>java -version
    java version "1.8.0_212"
    Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
    Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)
    
  4. 监控

    • 使用 JConsole 监控

      路径:D:\...\jdk1.8.0_212\bin\jconsole.exe

      1. 打开 JConsole2. 选择 远程连接 → 输入 IP:指定 JMX 端口3. 如果关闭认证/SSL,则为“不安全连接”4. 进入控制台即可查看 JVM 的内存、线程、类加载等信息
      

      在这里插入图片描述

    • 使用 JVisualVM 监控

      路径:D:\...\jdk1.8.0_212\bin\jvisualvm.exe

      1. 打开 JVisualVM2. 添加远程主机 → 输入主机名/IP(不用带端口)3. 添加 JMX 连接 → 输入 IP:指定 JMX 端口4. 双击连接,即可查看监控效果
      


      在这里插入图片描述


二:监控命令

1)jps

  • 作用:查看正在运行的 Java 进程(类似 ps -ef | grep java,但只显示 Java 进程)。

  • 常用命令

    # 查看所有 Java 进程
    jps# 查看详细信息(主类名、JVM参数等)
    jps -lvm | grep tomcat
    

2)jstack

  • 作用:查看指定 Java 进程的线程信息,用于分析线程状态、死锁等问题。

  • 操作步骤

    线程状态说明:

    1. NEW:新建
    2. RUNNABLE:就绪
    3. RUNNING:运行中
    4. BLOCKED:阻塞(常见于 IO)
    5. DEAD:死亡
    # 查看 Java 进程 PID
    jps
    80177 Bootstrap# 查看该进程的线程栈信息
    jstack 80177# 仅查看线程状态
    jstack 80177 | grep -i state
    

3)jmap

  • 作用:查看或导出 JVM 内存信息

  • 常用命令

    # 查看 JVM 内存使用情况
    jmap -heap 80177# 导出 JVM 内存镜像文件(用于分析)
    jmap -dump:format=b,file=8080.hprof 80177
    

4)MAT 工具分析

  • 作用图形化分析 .hprof 堆内存镜像文件,排查内存泄漏、对象占用过大等问题。

  • 使用步骤

    1. 在 Linux 导出堆文件:

      jmap -dump:format=b,file=8080.hprof 80177sz 8080.hprof   # 传输到本地
      
    2. Windows/Mac/Linux 安装 MAT

      下载地址: Memory Analyzer (MAT) | The Eclipse Foundation

      在这里插入图片描述
      在这里插入图片描述

    3. 打开 .hprof 文件

      1. 欢迎页选择 Open a Heap Dump2. 选择 Leak Suspects Report 查看内存泄漏报告
      

三:监控脚本

show-busy-java-thread.sh 显示当前环境中,所有繁忙的java线程. 以百分数显示使用率最高的前几个线程.

#!/bin/bash
# @Function
# Find out the highest cpu consumed threads of java, and print the stack of these threads.
#
# @Usage
#   $ ./show-busy-java-threads.sh
#
# @author Jerry Leereadonly PROG=`basename $0`
readonly -a COMMAND_LINE=("$0" "$@")usage() {cat <<EOF
Usage: ${PROG} [OPTION]...
Find out the highest cpu consumed threads of java, and print the stack of these threads.
Example: ${PROG} -c 10Options:-p, --pid       find out the highest cpu consumed threads from the specifed java process,default from all java process.-c, --count     set the thread count to show, default is 5-h, --help      display this help and exit
EOFexit $1
}readonly ARGS=`getopt -n "$PROG" -a -o c:p:h -l count:,pid:,help -- "$@"`
[ $? -ne 0 ] && usage 1
eval set -- "${ARGS}"while true; docase "$1" in-c|--count)count="$2"shift 2;;-p|--pid)pid="$2"shift 2;;-h|--help)usage;;--)shiftbreak;;esac
done
count=${count:-5}redEcho() {[ -c /dev/stdout ] && {# if stdout is console, turn on color output.echo -ne "\033[1;31m"echo -n "$@"echo -e "\033[0m"} || echo "$@"
}yellowEcho() {[ -c /dev/stdout ] && {# if stdout is console, turn on color output.echo -ne "\033[1;33m"echo -n "$@"echo -e "\033[0m"} || echo "$@"
}blueEcho() {[ -c /dev/stdout ] && {# if stdout is console, turn on color output.echo -ne "\033[1;36m"echo -n "$@"echo -e "\033[0m"} || echo "$@"
}# Check the existence of jstack command!
if ! which jstack &> /dev/null; then[ -z "$JAVA_HOME" ] && {redEcho "Error: jstack not found on PATH!"exit 1}! [ -f "$JAVA_HOME/bin/jstack" ] && {redEcho "Error: jstack not found on PATH and $JAVA_HOME/bin/jstack file does NOT exists!"exit 1}! [ -x "$JAVA_HOME/bin/jstack" ] && {redEcho "Error: jstack not found on PATH and $JAVA_HOME/bin/jstack is NOT executalbe!"exit 1}export PATH="$JAVA_HOME/bin:$PATH"
fireadonly uuid=`date +%s`_${RANDOM}_$$cleanupWhenExit() {rm /tmp/${uuid}_* &> /dev/null
}
trap "cleanupWhenExit" EXITprintStackOfThread() {local linelocal count=1while IFS=" " read -a line ; dolocal pid=${line[0]}local threadId=${line[1]}local threadId0x=`printf %x ${threadId}`local user=${line[2]}local pcpu=${line[4]}local jstackFile=/tmp/${uuid}_${pid}[ ! -f "${jstackFile}" ] && {{if [ "${user}" == "${USER}" ]; thenjstack ${pid} > ${jstackFile}elseif [ $UID == 0 ]; thensudo -u ${user} jstack ${pid} > ${jstackFile}elseredEcho "[$((count++))] Fail to jstack Busy(${pcpu}%) thread(${threadId}/0x${threadId0x}) stack of java process(${pid}) under user(${user})."redEcho "User of java process($user) is not current user($USER), need sudo to run again:"yellowEcho "    sudo ${COMMAND_LINE[@]}"echocontinuefifi} || {redEcho "[$((count++))] Fail to jstack Busy(${pcpu}%) thread(${threadId}/0x${threadId0x}) stack of java process(${pid}) under user(${user})."echorm ${jstackFile}continue}}blueEcho "[$((count++))] Busy(${pcpu}%) thread(${threadId}/0x${threadId0x}) stack of java process(${pid}) under user(${user}):"sed "/nid=0x${threadId0x} /,/^$/p" -n ${jstackFile}done
}ps -Leo pid,lwp,user,comm,pcpu --no-headers | {[ -z "${pid}" ] &&awk '$4=="java"{print $0}' ||awk -v "pid=${pid}" '$1==pid,$4=="java"{print $0}'
} | sort -k5 -r -n | head --lines "${count}" | printStackOfThread

四:Java 系统负载与性能排查流程

1)初步观察系统负载

  • 使用 w / top / uptime 查看系统整体负载

  • 如果 负载 > CPU 核心数 × 60%~70%,说明系统存在瓶颈

  • 命令:

    w
    uptime
    lscpu
    top -1
    

2)判断负载来源

  • CPU 负载

    • 命令:top → 观察 %us(用户态 CPU 占比)
    • 若 CPU 过高,说明是计算型压力
    • 工具:ps aux / htop / top
  • IO 负载

    • 命令:top → 观察 %wa(I/O 等待占比)
    • 若 IO 过高,说明磁盘或网络瓶颈
    • 工具:iotop

3)确定问题进程

  • 使用 ps aux / htop / top 查找占用 CPU/内存较高的进程
  • 获取 Java 进程 ID (PID)

4)进一步分析

  1. 查看日志

    • 检查应用日志(如 catalina.out),排查异常或错误
  2. 线程分析

    • 使用 jstack 查看线程堆栈信息

    • 关注线程状态(Runnable、Blocked、Waiting 等)

    • 示例:

      jstack <pid>
      jstack <pid> | grep -i state
      
  3. JVM 内存分析

    • 导出堆内存镜像:

      jmap -dump:format=b,file=/root/jvm.hprof <pid>
      
    • 查看 JVM 内存使用情况:

      jmap -heap <pid>
      
  4. 堆文件分析

    • .hprof 文件传至本地
    • 使用 MemoryAnalyzer Tool (MAT)Eclipse MAT 插件打开
    • 重点查看:
      • Leak Suspects Report(内存泄漏嫌疑报告)
      • 对象占用情况(哪些类实例过多/占用大)

5)问题解决与总结

  1. 根据 jstack 定位线程死锁/阻塞点
  2. 根据 jmap + MAT 分析内存泄漏问题
  3. 结合日志和监控,优化代码或调整 JVM 参数
  4. 验证问题是否解决

总结

📌 本节重点回顾

  • 监控工具

    • 学会了通过 JMX 远程监控,结合 JConsole、JVisualVM 等工具查看 JVM 内存、线程、类加载等运行状态。

    • 掌握了在 Linux 修改 catalina.sh 启动参数 的方法,开启远程监控端口。

  • 监控命令

    • jps → 查看 Java 进程

    • jstack → 分析线程堆栈,定位死锁/阻塞

    • jmap → 导出内存快照,分析堆使用情况

    • 配合 MAT 工具 图形化分析 .hprof,排查内存泄漏

  • 监控脚本

    • 通过 show-busy-java-thread.sh 快速定位 最耗 CPU 的线程,并打印线程堆栈信息,便于排错。
  • 性能排查流程

    • 先看系统整体负载(w、top、uptime)

    • 判断是 CPU 负载 还是 IO 负载

    • 确定问题进程 → 结合 jstack / jmap 分析

    • 使用 日志 + 堆分析工具(MAT) 找出瓶颈

    • 优化代码、JVM 参数或系统资源配置

至此,你已经掌握了 Tomcat 与 JVM 的监控手段,能从 进程 → 线程 → 内存 → 系统层面 全方位排查性能问题。
下一篇将进入 Tomcat 优化与安全加固,进一步打造稳定、高性能的生产环境。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95334.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95334.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/95334.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

技术干货丨HyperMesh 新界面功能与技术升级解析

全文内容选自 Altair 区域技术交流会华东站Altair 高级技术经理 张晨《HyperWorks 2025&#xff1a;下一代建模可视化和二次开发平台》演讲1、引言今天我为大家介绍 HyperMesh——这个大家既熟悉又陌生的工具。说熟悉&#xff0c;是因为它一直是工程仿真领域的主流建模软件&…

《IC验证必看|随机稳定性 / 再现性》

同一用例 A 机 pass、B 机 fail&#xff1f;——SystemVerilog 随机稳定性 / 可复现性全攻略&#xff08;含代码与排查清单&#xff09;你该到什么水平&#xff1f;&#xff08;对标 20k / 25k / 30k&#xff09; 20k&#xff08;入门会用&#xff09; 会 randomize()、$urando…

字符编码的本质

目的 最近做一个加密方面的研究&#xff0c;加密之后的二进制&#xff0c;通过转码之后&#xff0c;再也找不回之前的二进制了。 怎么试都不行&#xff0c;真是非常得奇怪&#xff01;&#xff01;&#xff01;&#xff01;先说说字符编码基础知识 在信息技术的海洋中&#xff…

网格图--Day03--网格图DFS--2658. 网格图中鱼的最大数目,1034. 边界着色,1020. 飞地的数量

网格图–Day03–网格图DFS–2658. 网格图中鱼的最大数目&#xff0c;1034. 边界着色&#xff0c;1020. 飞地的数量 今天要训练的题目类型是&#xff1a;【网格图DFS】&#xff0c;题单来自灵艾山茶府。 适用于需要计算连通块个数、大小的题目。 部分题目做法不止一种&#xff0…

新能源车焊接中发那科机器人保护气省气方法

在新能源汽车制造领域&#xff0c;焊接工艺是保障车身结构强度与安全性的关键环节&#xff0c;发那科焊接机器人凭借高精度与稳定性成为产线主力设备。保护气体消耗在焊接成本中占比显著&#xff0c;寻找高效省气方法成为行业降本增效的核心需求。WGFACS节气装置以智能化控制技…

CornerNet2025再研究---将目标检测问题视作关键点检测与配对

CornerNet于2019年3月份提出&#xff0c;CW近期回顾了下这个在当时引起不少关注的目标检测模型&#xff0c;它的亮点在于提出了一套新的方法论——将目标检测转化为对物体成对关键点(角点)的检测。通过将目标物体视作成对的关键点&#xff0c;其不需要在图像上铺设先验锚框(anc…

【C++】vector(2)

目录 1. insert的实现 2. 迭代器失效 2.1 迭代器失效的两种情况 指向已释放的内存&#xff08;物理失效&#xff09; 元素移动导致迭代器指向错误&#xff08;逻辑失效&#xff09; 2.2 修改代码 3. erase的实现 ​编辑修改代码 4. resize的实现 5. 构造函数 5.1 默认…

机器翻译:python库translatepy的详细使用(集成了多种翻译服务)

更多内容请见: 机器翻译修炼-专栏介绍和目录 文章目录 一、translatepy概述 1.1 translatepy介绍 1.1 安装 二、基本使用 2.1 初始化 `Translator` 2.2 文本翻译 2.3 语言检测 2.4 获取翻译备选方案 2.5 单词音标获取 2.6 语音合成 2.7 例句查询 2.8 拼写检查 三、高级功能 3.…

Spring Bean生命周期的完全指南

简介&#xff1a;超越Bean——揭开Spring Bean的隐秘生活 想象一场复杂宏大的舞台剧。作为观众&#xff0c;我们看到的是最终的演出——一个流畅运行的应用程序。但在这光鲜的幕后&#xff0c;隐藏着一套严谨细致的流程&#xff1a;选角&#xff08;实例化Bean&#xff09;、试…

网络安全A模块专项练习任务九解析

任务九&#xff1a;Linux操作系统安全配置-2任务环境说明&#xff1a; (Linux)系统&#xff1a;用户名root&#xff0c;密码1234561. 设置禁止使用最近用过的6个旧密码&#xff0c;将配置文件中对应的部分截图&#xff1b;编辑/etc/pam.d/system-auth文件&#xff0c;找到passw…

Linex进程管理

一、进程查看命令1.pstree用于查看进程树之间的关系&#xff0c;谁是父进程&#xff0c;谁是子进程&#xff0c;可以清楚的看出来是谁创建了谁语法&#xff1a;pstree [选项] -A各进程树之间的连接以ASCII码字符来连接-U各进程树之间的连接以utf8字符来连接&#xff0c;某些终…

手写MyBatis第47弹:Interceptor接口设计与Invocation上下文传递机制--MyBatis动态代理生成与方法拦截的精妙实现

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;&#x1f525;&…

自动驾驶中的传感器技术37——Lidar(12)

这里对当前Lidar中的一些常见问题进行专项论述。首先以禾赛Lidar为例&#xff0c;列出相关参数&#xff0c;以备论述。 图1 禾赛AT128参数图2 禾赛AT360参数图3 禾赛AT1440参数图4 禾赛AT128可靠性验证项图5 禾赛AT128产品证书1、Lidar的线束是什么&#xff0c;由什么决定&…

Meteor主题友链页面自研

发布于&#xff1a;Eucalyptus-Blog Meteor主题虽然设计简约现代&#xff0c;但由于缺乏原生的友情链接管理功能&#xff0c;许多博主只能将友情链接勉强添加在网站底部&#xff0c;这不仅影响页面美观&#xff0c;也不便于访客查找和互动&#xff1b;为了解决这一痛点&#xf…

QT控件QPlainTextEdit、QTextEdit与QTextBrowser的区别

一.主要功能对比二.关键功能差异1.文本类型支持QPlainTextEdit&#xff1a;仅支持纯文本&#xff08;Plain Text&#xff09;&#xff0c;不处理任何格式&#xff08;如字体、颜色、链接、图片等&#xff09;。文本以原始字符形式存储&#xff0c;适合处理日志、代码、配置文件…

【思考】WSL是什么

WSL WSL是什么呢&#xff1f; WSL 是 windows subsystem for linux 的简写&#xff0c;指的是 windows10 的一个子系统&#xff0c;这个子系统的作用是在 windows 下运行 linux 操作系统。 有了WSL&#xff0c;就可以在 windows10 中运行linux操作系统了。许多在 linux 种运行的…

基于单片机智能饮水机/智能热水壶

传送门 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品题目速选一览表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品题目功能速览 概述 基于单片机的智能饮水机系统通过嵌入式技术实现水温控制、水量监测及用户交互功能。系统采用STM3…

Unity游戏打包——iOS打包基础、传包

本文由 NRatel 历史笔记整理而来&#xff0c;如有错误欢迎指正。 相关参考文档 Unity文档 -> 平台开发 -> IOS https://docs.unity3d.com/cn/2021.3/Manual/iphone.html Unity导出的Xcode 项目的结构 Modifying an Xcode project use Xcode.PBXProject. https://doc…

pyside6小项目:进制转换器

from PySide6.QtUiTools import QUiLoader from PySide6.QtWidgets import QApplication,QWidgetclass MyWindow(QWidget):def __init__(self):super().__init__()self.ui QUiLoader().load(trans.ui)self.ui.show()#stor data type dictionaryself.lengthVar {米:100, 千米:…

再见 K8s!3款开源的云原生部署工具

前文&#xff0c;和大家分享了云原生中的核心工具 K8s&#xff1a; 关于 K8s&#xff1a;入门&#xff0c;这篇就够了 K8s是个好东西&#xff0c;就是上手门槛有点高。这不&#xff0c;需求就来了&#xff1f; 有需求&#xff0c;就有工具。 为了解决K8s的配置难题&#xf…