CAT 监控 3.1.0 常用 CLI 命令与工具详解

详解 CAT(Central Application Tracking)3.1.0 服务端运维全命令链:Maven 构建链、MySQL 初始化与 config 表维护、Tomcat 启停脚本、JVM 堆限 jps/jcmd 实测验证、端口与 checkpoint 运维接口、日志 grep 排障,含 2280 监听丢失完整排障实录。

CAT 监控CAT可观测性2026/10/23

CAT 监控 3.1.0 常用 CLI 命令与工具详解

目标:把 CAT(Central Application Tracking,大众点评开源 APM)3.1.0 服务端日常运维所依赖的全部命令行工具——Maven 构建链、MySQL 初始化与维护、Tomcat 部署启停脚本、JVM 诊断工具(jps/jcmd/jstat/jstack)、端口与 HTTP 运维接口、日志排查 grep 模式——逐条给出实测命令与真实回显,形成一份「照着敲即可运维」的命令手册。已在 Ubuntu 22.04 服务器(JDK 1.8.0_504 + Maven 3.6.3 + MySQL 5.7.44 + Tomcat 9.0.123 + CAT 3.1.0)逐条实测通过,含 2280 端口监听丢失的完整排障实录。

一、环境信息

本文所有命令与回显均在以下环境实测采集,与《CAT 监控 3.1.0 安装指南》为同一套部署(命令独立可执行,无需依赖该篇):

  • 操作系统:Ubuntu 22.04 LTS(x86_64,内核 6.8.0-138-generic)
  • CAT 服务端机器:IP 10.89.66.3,主机名 cat-server.local;源码 /opt/cat-src、Tomcat /opt/tomcat、CAT 配置与数据 /data/appdatas/cat/、日志 /data/applogs/cat/
  • 数据库机器:IP 10.89.66.2,MySQL 5.7.44(--max-allowed-packet=1G 启动),库名 cat,示例账号 root/密码 q1w2e3r4
  • JDK:OpenJDK 1.8.0_504(/usr/lib/jvm/java-8-openjdk-amd64,jps/jcmd/jstat/jstack/jmap 随 JDK 8 附带)
  • Maven:3.6.3(Ubuntu 22.04 仓库自带)
  • Web 容器:Apache Tomcat 9.0.123(/opt/tomcat),部署包 webapps/cat.war(61,600,678 字节)
  • JVM 堆配置:setenv.sh 设定 -Xms256m -Xmx512m(验证环境口径;本文第七章给出生效验证的三种实测手段)
  • 端口:控制台 HTTP 8080、客户端上报 TCP 2280
  • 控制台账号:admin / q1w2e3r4(setenv.sh 中 -DCAT_ADMIN_PWD 所设)

⚠️ 本文所指 CAT 均为 Central Application Tracking 应用监控系统,与 Linux Shell 同名文件查看命令无关;但下文确实会用 Shell 的 cat 命令查看配置文件,注意区分语境。

二、工具概览

CAT 3.1.0 服务端本身不提供独立的管理 CLI,日常运维命令围绕它的四个运行环节展开:构建期(Maven)、存储期(MySQL)、运行期(Tomcat/JVM)、观测期(端口/HTTP 接口/日志)。先用一张总览表建立全景,再分章逐条实测:

环节工具/命令用途本文章节
构建mvn -version / mvn clean install -DskipTests构建环境自检 / 源码构建 WAR 包四
存储mysql(建库/导脚本/查表/查配置中心)初始化 cat 库、验证 26 张表、查 config 配置中心五
运行version.sh / configtest.sh / startup.sh / shutdown.sh版本自检 / 配置校验 / 启动 / 停止六
运行setenv.shJVM 参数与控制台密码的唯一修改位置六
诊断jps / jcmd / jstat / jstack / jmap进程与参数确认 / 堆与线程诊断七
观测netstat / ps / curl端口监听 / 进程确认 / 控制台与 checkpoint 接口八
排障grep / tail(对服务端日志)角色生效、连接状态、报错定位九

💡 说明:JVM 诊断工具有多套,选型不影响正确性但影响效率——

工具原理强项限制
jpsAttach 机制枚举 JVM最轻量的进程/参数确认只见本机当前用户进程
jcmdAttach 机制发指令JDK 8 下功能最全(flags/堆/线程/直方图一把梭)需同 UID;部分子命令需解锁商业特性
jstatAttach 采样 GC 计数定时连续观察 GC 趋势只读计数,无对象明细
jstackAttach 抓线程快照线程级排障(死锁/挂起)一次性快照
jmap(-heap/-histo)SA 独立调试器,依赖 ptrace堆详情与类直方图受内核 ptrace 限制最深(见 7.5 实测)

本文实测环境为 JDK 8,日常以 jcmd 为主、jps/jstat 做轻量确认、jstack 抓线程;jmap 仅在需要堆转储时使用。

三、前置条件

逐条执行本文命令前,确认以下前置已满足(每条附验证命令,输出均实测自本环境):

  1. JDK 8 已安装且为默认 java(jps/jcmd 等 JDK 工具随包附带):
java -version

实测输出:

openjdk version "1.8.0_504"
OpenJDK Runtime Environment (build 1.8.0_504-8u504-ga-1ubuntu1~22.04.3-b01)
OpenJDK 64-Bit Server VM (build 25.504-b01, mixed mode)
  1. CAT 服务端已在运行(Tomcat 进程存在、8080 可达;首次部署步骤见《CAT 监控 3.1.0 安装指南》):
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/cat/r/

实测输出:

200
  1. MySQL 客户端可用且 cat 库已初始化:
mysql -h10.89.66.2 -uroot -pq1w2e3r4 -e "SELECT COUNT(*) AS table_count FROM information_schema.tables WHERE table_schema='cat';" 2>/dev/null

实测输出:

table_count
26

💡 说明:2>/dev/null 用于吞掉 mysql 客户端「Using a password on the command line」的警告行(密码在命令行的安全提醒),后文 mysql 命令同此处理;生产环境建议改用 mysql_config_editor 或交互式输入密码。

四、Maven 构建工具链命令

CAT 服务端以源码发行,升级版本、打补丁、做内部定制都绕不开 Maven 构建。本章覆盖构建环境自检、构建执行、产物核对三条命令。

4.1 mvn -version:构建环境自检

构建前先确认 Maven 版本与其绑定的 JDK——CAT 3.1.0 必须用 JDK 8 构建(JDK 11+ 会因旧版 Maven 插件不兼容编译失败),mvn -version 的 Java version 行是唯一可信判据:

mvn -version

实测输出:

Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 1.8.0_504, vendor: Ubuntu, runtime: /usr/lib/jvm/java-8-openjdk-amd64/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "6.8.0-138-generic", arch: "amd64", family: "unix"

逐行解读:Java version: 1.8.0_504 与目标一致即构建环境就绪;platform encoding: ANSI_X3.4-1968 是系统 locale 为 POSIX 时的 ASCII 别名,构建 CAT 无碍(源码编译编码由 pom 指定),但若自行修改含中文注释的源文件,建议 export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 后再构建。

⚠️ 若 Java version 显示 11.x/17.x,Maven 用的是默认 JDK 而非 java 命令指向的那个。先切换系统默认再核对:update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java,并在构建前 export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64。

4.2 mvn clean install -DskipTests:源码构建 WAR 包

在源码目录执行官方构建命令(-DskipTests 跳过测试、-B 关闭进度条便于落日志):

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
cd /opt/cat-src
mvn clean install -DskipTests -B

实测输出(首尾节选,全程 3 分 23 秒;首次构建需下载全部依赖,视网络 5-30 分钟):

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for CAT 3.1.0:
[INFO]
[INFO] cat-parent ......................................... SUCCESS [  1.286 s]
[INFO] cat-core ........................................... SUCCESS [ 20.196 s]
[INFO] cat-client ......................................... SUCCESS [  4.970 s]
[INFO] cat-consumer ....................................... SUCCESS [  2.600 s]
[INFO] cat-alarm .......................................... SUCCESS [  2.235 s]
[INFO] cat-hadoop ......................................... SUCCESS [  1.442 s]
[INFO] cat-home ........................................... SUCCESS [01:03 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] Total time:  03:23 min
[INFO] Finished at: 2026-10-22T23:33:53Z
[INFO] ------------------------------------------------------------------------

要点:cat-home 模块耗时最长(打 WAR 包),其余模块秒级;任一模块 FAILURE 时往上翻 [ERROR] 段落定位(九成是 JDK 版本或依赖下载超时,见《CAT 监控 3.1.0 安装指南》FAQ Q2/Q3)。

4.3 构建产物核对

ls -la /opt/cat-src/cat-home/target/cat-home.war

实测输出:

-rw-r--r-- 1 root root 61600678 Oct 22 23:33 /opt/cat-src/cat-home/target/cat-home.war

⚠️ 产物名为 cat-home.war,部署时必须重命名为 cat.war(CAT 页面资源按 /cat 上下文路径硬编码);构建后建议顺手核对字节数与本次构建一致,作为「部署包来自哪次构建」的追溯依据。

五、MySQL 初始化与维护命令

CAT 的报表数据、配置中心(config 表)全部落 MySQL,数据库侧命令分初始化与日常维护两组。以下命令在数据库机器(10.89.66.2)或任一装有 mysql 客户端的机器上执行。

5.1 建库并导入官方脚本

初始化只需两条命令(脚本 CatApplication.sql 来自源码 script/ 目录):

mysql -h10.89.66.2 -uroot -pq1w2e3r4 -e "CREATE DATABASE IF NOT EXISTS cat DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" 2>/dev/null

(无回显即成功。)

mysql -h10.89.66.2 -uroot -pq1w2e3r4 cat < /opt/cat-src/script/CatApplication.sql 2>/dev/null

(无回显即成功;导入耗时约 1-2 秒。)

5.2 表数量与表清单验证

mysql -h10.89.66.2 -uroot -pq1w2e3r4 -e "USE cat; SHOW TABLES;" 2>/dev/null

实测输出:

alert
alert_summary
alteration
baseline
businessReport
business_config
config
config_modification
daily_report_content
dailyreport
hostinfo
hourly_report_content
hourlyreport
metric_graph
metric_screen
monthly_report_content
monthreport
operation
overload
project
server_alarm_rule
task
topologyGraph
user_define_rule
weekly_report_content
weeklyreport

共 26 张表(计数验证用 5.1 前置条件中的 information_schema 查询)。表前缀含义速览:dailyreport/weeklyreport/monthreport 及对应 *_content 是天/周/月报表主体;config/config_modification 是配置中心与其审计留痕;topologyGraph 存客户端路由;project 存接入的业务域。

5.3 config 配置中心表查询(日常最常用)

CAT 3.x 运行期权威配置都在 config 表,排查「改了配置怎么没生效」先看这张表的修改时间:

mysql -h10.89.66.2 -uroot -pq1w2e3r4 -e "SELECT name, modify_date FROM cat.config ORDER BY modify_date DESC LIMIT 5;" 2>/dev/null

实测输出:

name                    modify_date
capacityUpdateStatus    2026-10-23 06:10:09
sampleConfig            2026-10-23 00:22:42
server-config           2026-10-23 00:06:01
user-config             2026-10-22 23:49:01
resource-config         2026-10-22 23:49:01

逐行解读:sampleConfig 是消息采样率配置、server-config 是服务端角色(job-machine/alarm-machine 等)、user-config/resource-config 为控制台默认行;modify_date 即最近一次提交时间,与操作时间对得上说明提交入库成功。查看某行完整 XML 内容用 SELECT content FROM cat.config WHERE name='sampleConfig'\G。

5.4 max_allowed_packet 核验

官方要求调大该参数(报表单行内容很大),日常巡检一条命令确认:

mysql -h10.89.66.2 -uroot -pq1w2e3r4 -e "SHOW VARIABLES LIKE 'max_allowed_packet';" 2>/dev/null

实测输出:

Variable_name       Value
max_allowed_packet  1073741824

💡 说明:1073741824 即 1GB。若回显为默认 4194304(4M),天/周报表落库时会报 Packet too big 类错误,需在 my.cnf 加 max_allowed_packet=1G 并重启数据库。

六、Tomcat 部署与启停命令

CAT 服务端 WAR 跑在 Tomcat 里,启停与配置校验全部用 Tomcat 自带脚本(/opt/tomcat/bin/ 下)。所有脚本执行前先导出 JAVA_HOME,否则脚本报「Neither the JAVA_HOME nor the JRE_HOME environment variable is defined」。

6.1 version.sh:版本自检

确认 Tomcat 与 JVM 版本(升级/排障第一步):

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
/opt/tomcat/bin/version.sh

实测输出:

Server version: Apache Tomcat/9.0.123
Server built:   Oct 6 2026 18:59:20 UTC
Server number:  9.0.123.0
OS Name:        Linux
OS Version:     6.8.0-138-generic
Architecture:   amd64
JVM Version:    1.8.0_504-8u504-ga-1ubuntu1~22.04.3-b01
JVM Vendor:     Ubuntu
APR loaded:     false

Third-party libraries:
  ecj-4.20.jar: 3.26.0.v20210609-0549

6.2 configtest.sh:配置语法校验

改完 conf/server.xml 后校验语法(不真正启动):

/opt/tomcat/bin/configtest.sh

实测输出(节选,末行结论为关键):

Oct 23, 2026 6:38:18 AM org.apache.catalina.startup.Catalina load
INFO: Server initialization in [231] milliseconds

⚠️ 注意(实测踩坑):在运行中的实例上执行 configtest.sh,它会尝试初始化 Connector 并绑定 8080,与运行进程冲突而抛出:

SEVERE: Failed to initialize component [Connector["http-nio-8080"]]
Caused by: java.net.BindException: Address already in use

这是端口冲突的误报,不代表配置文件有语法错误。判读方法:只要输出里没有 org.xml.sax.SAXParseException 类解析异常,仅 BindException 即可认定配置语法本身通过;严谨做法是停机窗口内校验。

6.3 startup.sh:启动

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
/opt/tomcat/bin/startup.sh

实测输出:

Tomcat started.

启动后验证(CAT 就绪约需 10 秒,首次部署需 1-2 分钟):

sleep 15
netstat -ltn | grep -E ':(8080|2280)'

实测输出:

tcp6       0      0 :::8080                 :::*                    LISTEN
tcp6       0      0 :::2280                 :::*                    LISTEN
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/cat/r/

实测输出:

200

6.4 shutdown.sh:停止与残留确认

/opt/tomcat/bin/shutdown.sh

实测输出:无回显(脚本静默执行)。停止是异步的,需主动确认进程已退出:

sleep 6
jps -l

实测输出(6 秒后 Bootstrap 已退出,仅剩 jps 自身):

2630 sun.tools.jps.Jps

⚠️ 注意:shutdown.sh 偶发发完停止指令后进程长时间不退(旧连接未关闭时多见)。若 30 秒后 jps -l 仍见 Bootstrap,按第七章 jps -l 取 PID 后 kill -9 <PID> 清理再启动;重启前建议按 8.4 节调 checkpoint 保数据。

6.5 setenv.sh:JVM 参数与控制台密码修改位置

JVM 堆大小、CAT 配置目录、控制台密码全部集中在 /opt/tomcat/bin/setenv.sh(Tomcat 官方约定的自定义参数文件,catalina.sh 启动时自动加载)。查看当前内容:

cat /opt/tomcat/bin/setenv.sh

实测输出:

export CAT_HOME=/data/appdatas/cat/
CATALINA_OPTS="$CATALINA_OPTS -server -DCAT_HOME=$CAT_HOME -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Xms256m -Xmx512m -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -DCAT_ADMIN_PWD=q1w2e3r4"

修改示例(把堆调成 512MB 起步的口径,验证环境常用):编辑该文件将 -Xms256m -Xmx512m 改为目标值,保存后重启 Tomcat(6.4 + 6.3),并用第七章 7.2 的 jcmd VM.flags 验证生效。控制台密码改 -DCAT_ADMIN_PWD=<新密码>,账号固定为 admin(源码硬编码)。

七、JVM 运维与诊断命令

CAT 是常驻 Java 进程,堆溢出、线程挂起、GC 异常都用 JDK 自带工具诊断。本章每条命令实测,核心目标是回答两个问题:进程实际在用什么参数(7.1/7.2)、堆与线程现状如何(7.2-7.4)。

7.1 jps:进程与 JVM 参数确认

jps -l 列出本机全部 Java 进程(全限定主类名),是停止/清理前的标准定位手段:

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
jps -l

实测输出:

3336 sun.tools.jps.Jps
2668 org.apache.catalina.startup.Bootstrap

jps -v 直接回显每个进程的完整 JVM 参数,验证 setenv.sh 是否生效就看它(重点看 -Xms/-Xmx/-DCAT_HOME/-DCAT_ADMIN_PWD):

jps -v

实测输出:

3336 Jps -Dapplication.home=/usr/lib/jvm/java-8-openjdk-amd64 -Xms8m
2668 Bootstrap -Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dsun.io.useCanonCaches=false -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -DCAT_HOME=/data/appdatas/cat/ -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Xms256m -Xmx512m -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -DCAT_ADMIN_PWD=q1w2e3r4 -Dignore.endorsed.dirs= -Dcatalina.base=/opt/tomcat -Dcatalina.home=/opt/tomcat -Djava.io.tmpdir=/opt/tomcat/temp

回显中 -Xms256m -Xmx512m、-DCAT_HOME=/data/appdatas/cat/、-DCAT_ADMIN_PWD=q1w2e3r4 三个关键值与 setenv.sh 完全一致,即配置生效。过滤出关键参数的快捷写法:

jps -v | grep Bootstrap | grep -oE '\-Xms[0-9]+m \-Xmx[0-9]+m|CAT_HOME=[^ ]+|CAT_ADMIN_PWD=[a-z0-9]+'

实测输出:

-Xms256m -Xmx512m
CAT_HOME=/data/appdatas/cat/
CAT_ADMIN_PWD=q1w2e3r4

⚠️ 注意:-DCAT_ADMIN_PWD 会以明文出现在 jps -v 与 ps -ef 回显中,生产环境应把登录页限定在内网并收敛 ps 可见范围(或接受该风险换成 LDAP 认证:加 -DCAT_AUTH_TYPE=LDAP 及 CAT_LDAP_URL/CAT_LDAP_USER_DN_TPL)。

7.2 jcmd:JDK 8 全能诊断入口

jcmd <pid> help 先看目标进程支持哪些指令:

jcmd 2668 help

实测输出(节选,CAT 进程可用指令清单):

2668:
The following commands are available:
VM.unlock_commercial_features
JFR.configure
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help

① VM.flags——堆参数生效值验证(与 jps -v 互为印证,数值形式最精确):

jcmd 2668 VM.flags | tr ' ' '\n' | grep -E 'Xms|Xmx|HeapSize'

实测输出:

-XX:InitialHeapSize=268435456
-XX:MaxHeapSize=536870912

268435456 = 256MB、536870912 = 512MB,与 -Xms256m -Xmx512m 一一对应——这是堆限生效的数值级证据。

② GC.heap_info——堆分区实时水位:

jcmd 2668 GC.heap_info

实测输出:

2668:
 PSYoungGen      total 142848K, used 19650K [0x00000000f5580000, 0x0000000100000000, 0x0000000100000000)
  eden space 113152K, 17% used [0x00000000f5580000,0x00000000f68b0870,0x00000000fc400000)
  from space 29696K, 0% used [0x00000000fe300000,0x00000000fe300000,0x0000000100000000)
  to   space 30720K, 0% used [0x00000000fc400000,0x00000000fc400000,0x00000000fe200000)
 ParOldGen       total 175104K, used 44529K [0x00000000e0000000, 0x00000000eab00000, 0x00000000f5580000)
  object space 175104K, 25% used [0x00000000e0000000,0x00000000e2b7c788,0x00000000eab00000)
 Metaspace       used 43208K, capacity 44056K, committed 44248K, reserved 1087488K
  class space    used 5099K, capacity 5318K, committed 5376K, reserved 1048576K

解读:新生代 + 老年代合计约 310MB 已用,距 512MB 上限余量充足;ParOldGen 说明当前收集器为 Parallel GC(JDK 8 服务端模式默认),与 -server 匹配。

③ VM.command_line——进程启动参数完整快照(排障时确认「进程到底怎么起的」):

jcmd 2668 VM.command_line

实测输出(节选,jvm_args 行完整包含 setenv.sh 全部参数):

2668:
VM Arguments:
jvm_args: -Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties ... -DCAT_HOME=/data/appdatas/cat/ ... -Xms256m -Xmx512m ... -DCAT_ADMIN_PWD=q1w2e3r4 -Dignore.endorsed.dirs= -Dcatalina.base=/opt/tomcat ...
java_command: org.apache.catalina.startup.Bootstrap start
java_class_path (initial): /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar
Launcher Type: SUN_STANDARD

④ GC.class_histogram——对象直方图(排查内存涨势的对象级归因):

jcmd 2668 GC.class_histogram | head -14

实测输出:

2668:

 num     #instances         #bytes  class name
----------------------------------------------
   1:          3672       18812952  [B
   2:         74774        7947792  [C
   3:          9775        6155008  [Ljava.lang.Object;
   4:         74250        1782000  java.lang.String
   5:          3604        1009328  [I
   6:          10824        952512  java.lang.reflect.Method
   7:          7950         883024  java.lang.Class
   8:         26879        860128  java.util.concurrent.ConcurrentHashMap$Node
   9:         20943        670176  java.util.HashMap$Node
  10:          4244        465928  [Ljava.util.HashMap$Node;

⑤ VM.uptime——运行时长(判断进程是否近期重启过):

jcmd 2668 VM.uptime

实测输出:

2668:
153.621 s

7.3 jstat:GC 趋势连续观察

每秒采样一次、共 3 次,看 GC 计数与各区占用比(列含义:S0/S1 幸存区、E 新生代、O 老年代、M 元空间、YGC/FGC 及其耗时):

jstat -gcutil 2668 1000 3

实测输出:

  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
 26.57   0.00  99.59  12.85  97.87  94.92     16    0.100     2    0.040    0.140
 26.57   0.00  99.70  12.85  97.87  94.92     16    0.100     2    0.040    0.140
 26.57   0.00  99.73  12.85  97.87  94.92     16    0.100     2    0.040    0.140

解读:Eden 区 99%+ 但 YGC 次数稳定(3 秒内无新增)、FGC 仅 2 次且总耗时 0.04 秒,堆健康。巡检口径:FGC 次数持续增长或 FGCT 秒数陡增才需介入;CAT 空载时 Eden 会一直贴满属正常(等下一次 Minor GC)。

7.4 jstack:线程快照

jstack 2668 | head -18

实测输出(节选,首部与一个 CAT 业务线程):

2026-10-23 06:39:14
Full thread dump OpenJDK 64-Bit Server VM (25.504-b01 mixed mode):

"Attach Listener" #138 daemon prio=9 os_prio=0 tid=0x000079f70c001000 nid=0xbc5 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Cat-ModelService-17" #137 daemon prio=5 os_prio=0 tid=0x000079f63c004800 nid=0xb8f waiting on condition [0x000079f5cd5fe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000e0b71358> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:750)
        at org.unidal.helper.Threads$RunnableThread.run(Threads.java:294)

解读:Cat-ModelService-* 是 CAT 消息模型处理线程池,空闲时 WAITING 在队列 take() 上属正常;抓死锁用 jstack <pid> | grep -A5 deadlock(有死锁会输出 Found one Java-level deadlock 段落)。

7.5 jmap:堆转储与限制说明

jmap 的堆详情/直方图走 SA(Serviceability Agent)调试器,需要内核 ptrace 权限。本环境实测输出:

jmap -heap 2668

实测输出:

Attaching to process ID 2668, please wait...
ERROR: ptrace(PTRACE_ATTACH, ..) failed for 2668: Operation not permitted
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 2668: Operation not permitted

⚠️ 注意:Operation not permitted 的两种常见成因与处理——① 执行账号与目标进程属主不同(切换为同一 UID 执行,Tomcat 以何账号运行就用何账号执行 jmap);② 内核 yama/ptrace_scope 限制(临时放开:sysctl -w kernel.yama.ptrace_scope=0,生产放开前评估安全影响)。堆统计信息可无权限要求的 jcmd 2668 GC.heap_info(7.2 ②)与 jstat -gcutil(7.3)替代;确需完整堆转储时用 jcmd 2668 GC.heap_dump /tmp/cat-heap.hprof(走 Attach 机制,不依赖 ptrace)。

八、端口、进程与 HTTP 运维命令

8.1 netstat:端口监听验证

CAT 就绪的「铁标准」是两个端口都在监听——8080(控制台/上报 HTTP)与 2280(客户端 TCP 上报,官方注明不可改):

netstat -ltn | grep -E ':(8080|2280)'

实测输出:

tcp6       0      0 :::8080                 :::*                    LISTEN
tcp6       0      0 :::2280                 :::*                    LISTEN

任一端口缺失即服务不完整,按第九章日志命令定位(2280 缺失的完整排障见 FAQ Q1)。

8.2 ps:进程命令行确认

ps -ef | grep [j]ava

实测输出(节选,仅保留 CAT 的 java 进程行):

root      2668      1 15 06:37 ?        00:00:32 /usr/lib/jvm/java-8-openjdk-amd64/bin/java -Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties ... -server -DCAT_HOME=/data/appdatas/cat/ ... -Xms256m -Xmx512m ... -classpath /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar ... org.apache.catalina.startup.Bootstrap start

解读:确认属主(root)、启动时间(06:37)、完整参数与主类 org.apache.catalina.startup.Bootstrap。[j]ava 写法利用字符类避免 grep 匹配到 grep 自身,比 grep java | grep -v grep 少一截管道。

8.3 curl:控制台健康检查与登录会话

① 匿名可达性检查(巡检脚本用,不登录):

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/cat/r/

实测输出:

200

② 登录换取会话 Cookie(账号 admin,密码即 setenv.sh 的 -DCAT_ADMIN_PWD):

curl -s -m 8 -c /tmp/cc.txt --data-urlencode 'account=admin' \
  --data-urlencode 'password=q1w2e3r4' \
  --data-urlencode 'login=1' --data-urlencode 'op=login' \
  -o /dev/null -w 'login=%{http_code}\n' http://127.0.0.1:8080/cat/s/login
grep -c 'ct' /tmp/cc.txt

实测输出:

login=200
1

③ 带会话访问报表页(验证会话有效):

curl -s -m 8 -b /tmp/cc.txt -o /dev/null -w 'report_page=%{http_code}\n' 'http://127.0.0.1:8080/cat/r/t?op=transactions'

实测输出:

report_page=200

💡 说明:登录成功后服务端下发名为 ct 的凭证 Cookie(源码 Token.TOKEN = "ct"),Cookie 文件中 grep -c 'ct' 计到 1 即已种下;脚本化巡检时保存好 Cookie 文件可复用会话。

8.4 curl checkpoint:重启前数据保护

官方提供的运维接口,把内存中的实时消息落盘后再重启,重启后报表可恢复:

curl -s -o /dev/null -w '%{http_code}\n' 'http://127.0.0.1:8080/cat/r/home?op=checkpoint'

实测输出:

200

⚠️ 官方注意事项:checkpoint 应在每小时的整点后 10-55 分钟之间调用(避开整点小时报表落盘窗口);建议写进 Tomcat 的停止流程:curl ... op=checkpoint → shutdown.sh → jps -l 确认退出 → startup.sh。

九、日志查看与排障命令

CAT 的运行观测面在两份日志:服务端业务日志 /data/appdatas/cat/cat_<yyyymmdd>.log(CAT 自己写的,含消息链路/配置/角色)与 Tomcat 运行日志 /opt/tomcat/logs/catalina.out(WAR 部署、JVM 级异常)。注意 /data/applogs/cat/ 目录为客户端日志预留,服务端日志实际落在 /data/appdatas/cat/ 下。

9.1 服务端日志:cat_<日期>.log

按天滚动,文件名带日期。看当天最新动态:

tail -5 /data/appdatas/cat/cat_$(date +%Y%m%d).log

实测输出:

[10-23 06:35:30.827] [WARN] [ChannelManager] channel buf is is close when send msg! Attempts: 4281000
[10-23 06:35:34.771] [WARN] [ChannelManager] channel buf is not active ,current channel /127.0.0.1:2280
[10-23 06:35:34.771] [INFO] [ChannelManager] close channel /127.0.0.1:2280
[10-23 06:35:34.771] [INFO] [ChannelManager] start connect server/127.0.0.1:2280
[10-23 06:35:34.772] [ERROR] [ChannelManager] Error when try connecting to /127.0.0.1:2280

(此为 2280 故障期间的实测片段,修复过程见 FAQ Q1。)

9.2 Tomcat 运行日志:catalina.out

部署、启停、JVM 级报错都在这里,定位启动耗时与部署结果:

grep -E 'Server startup|Deploying web application archive' /opt/tomcat/logs/catalina.out | tail -4

实测输出:

23-Oct-2026 00:06:49.736 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/opt/tomcat/webapps/cat.war]
23-Oct-2026 00:06:54.207 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [4493] milliseconds

(Server startup in 后的毫秒数即启动耗时;首次部署需解包 WAR 约 130 秒,后续重启 5 秒级。)

9.3 常用 grep 模式速查

以下模式覆盖日常 90% 排障场景,均在当前环境实测:

① 服务端角色生效确认(重启后必查):

grep 'CAT server is running' /data/appdatas/cat/cat_$(date +%Y%m%d).log | tail -3

实测输出:

[10-23 06:37:41.454] [INFO] [ServerConfigManager] CAT server is running with hdfs,false
[10-23 06:37:41.454] [INFO] [ServerConfigManager] CAT server is running with alert,true
[10-23 06:37:41.454] [INFO] [ServerConfigManager] CAT server is running with job,true

② 2280 服务端 socket 生命周期(判断消息接收端口起没起):

grep 'TcpSocketReceiver' /data/appdatas/cat/cat_$(date +%Y%m%d).log

实测输出(节选,含一次完整「起→停→再起」周期):

[10-23 00:00:51.931] [INFO] [TcpSocketReceiver] start netty server!
[10-23 00:06:16.065] [INFO] [TcpSocketReceiver] start shutdown socket, port 2280
[10-23 00:06:16.070] [INFO] [TcpSocketReceiver] shutdown socket success
[10-23 00:06:53.863] [INFO] [TcpSocketReceiver] start netty server!

判读要点:健康状态下最后一条应为 start netty server!;若最后一条是 shutdown socket success 而其后无 start netty server!,即 2280 监听已丢失(FAQ Q1 的判定依据)。

③ 客户端连接成功确认:

grep 'Connected to CAT server' /data/appdatas/cat/cat_$(date +%Y%m%d).log | tail -2

实测输出:

[10-23 00:06:54.324] [INFO] [ChannelManager] Connected to CAT server at /127.0.0.1:2280
[10-23 00:06:54.324] [INFO] [ChannelManager] success when init CAT server, new active holderactive future :/127.0.0.1:2280 index:0 ip:127.0.0.1 server config:127.0.0.1:2280;

④ 数据库连接失败检索(起不来时先查):

grep -c 'Error when connecting to JDBC' /data/appdatas/cat/cat_$(date +%Y%m%d).log

实测输出:

0

(0 表示当日无数据库连接失败;非 0 时取一条看完整报错,典型为 MySQL 8 兼容性问题,处理见《CAT 监控 3.1.0 安装指南》FAQ Q1。)

⑤ 本地数据目录水位(消息落盘文件与报表缓存):

ls /data/appdatas/cat/bucket/
du -sh /data/appdatas/cat/bucket/

实测输出:

dump
report
2.5M    /data/appdatas/cat/bucket/

(dump/ 存消息落盘文件、report/ 存报表缓存;磁盘巡检关注 du 增长速率,按 server.xml 的 local-report-storage-time=7 默认保留 7 天滚动清理。)

十、注意事项

  1. 修改 setenv.sh 后必须重启才生效:JVM 参数只在进程启动时读取;改完执行 6.4 停止 + 6.3 启动,并用 7.1 jps -v 与 7.2 jcmd VM.flags 双重验证。
  2. 堆大小按环境分层:验证环境 256-512MB 实测稳定(本文全程该配置,jcmd GC.heap_info 显示余量充足);生产按官方建议 10G 级堆并追加 GC 参数,改动同样落在 setenv.sh。
  3. 2280 端口不可改:客户端上报端口硬编码约定,防火墙放行 TCP 2280;客户端指向该端口的配置在 /data/appdatas/cat/client.xml。
  4. jps/jcmd 看不到进程时:确认执行账号与 Tomcat 进程属主一致(ps -ef 第 1 列),并确认 JAVA_HOME 指向与目标进程相同的 JDK 安装。
  5. 密码明文可见面:-DCAT_ADMIN_PWD 会出现在 jps -v/ps -ef/jcmd VM.command_line 回显中(7.1/7.2 实测可见),控制台务必限制在内网访问。
  6. 日志文件名带日期:跨天排查用 cat_$(date +%Y%m%d).log 取当天,历史问题按日期取对应文件。

十一、常见问题(FAQ)

Q1:控制台 200 可访问,但日志持续刷 Error when try connecting to /127.0.0.1:2280,且 netstat 无 2280 监听,怎么办?

本文实测遇到的完整排障过程(当日真实案例):

  • 现象:控制台正常(curl http://127.0.0.1:8080/cat/r/ 返回 200),但 netstat -ltn | grep 2280 无输出,服务端日志每 3 秒刷一轮:
    [10-23 06:35:34.771] [WARN] [ChannelManager] channel buf is not active ,current channel /127.0.0.1:2280
    [10-23 06:35:34.772] [ERROR] [ChannelManager] Error when try connecting to /127.0.0.1:2280
    
    当日该错误累计刷了 2182 次(grep -c 统计)。
  • 定位:按 9.3 ② 查 2280 socket 生命周期——
    grep 'TcpSocketReceiver' /data/appdatas/cat/cat_$(date +%Y%m%d).log
    
    发现最后一次 socket 事件是 shutdown socket success(00:32:21,此前一次服务端配置提交触发的内部关闭),其后再无 start netty server!——2280 的服务端监听随该次内部关闭后未重新拉起,而 Tomcat 主进程还活着,于是客户端线程无限重连。
  • 解决:重启 Tomcat 让 CAT 模块完整初始化(先 checkpoint 保护数据,见 8.4):
    curl -s -o /dev/null -w '%{http_code}\n' 'http://127.0.0.1:8080/cat/r/home?op=checkpoint'
    /opt/tomcat/bin/shutdown.sh
    
    (shutdown 后 jps -l 确认 Bootstrap 退出,见 6.4。)
    /opt/tomcat/bin/startup.sh
    
    实测输出:
    Tomcat started.
    
  • 验证:端口恢复 + 日志确认,两步实测:
    netstat -ltn | grep -E ':(8080|2280)'
    
    tcp6       0      0 :::8080                 :::*                    LISTEN
    tcp6       0      0 :::2280                 :::*                    LISTEN
    
    grep 'start netty server' /data/appdatas/cat/cat_$(date +%Y%m%d).log | tail -1
    
    [10-23 06:37:41.567] [INFO] [TcpSocketReceiver] start netty server!
    

Q2:configtest.sh 报 Address already in use,是配置改错了吗?

不是。configtest 会尝试绑定 8080,与运行中的实例冲突(6.2 节实测完整堆栈)。只要没有 SAXParseException 类报错即语法通过;要完全避开误报,在停机窗口执行 configtest。

Q3:shutdown.sh 后 jps -l 仍能看到 Bootstrap?

优雅停止依赖进程自行退出,偶发因未关闭的连接挂住。等待 30 秒仍不退则 kill -9 <jps -l 查得的 PID> 强制清理后重新 startup;强制停止前建议先调 checkpoint(8.4)减少报表数据损失。

Q4:jmap -heap 报 Operation not permitted?

jmap 堆分析走 SA/ptrace 通道,受执行账号与内核 ptrace 策略双重约束(7.5 节实测报错全文)。处理:换与进程同 UID 的账号执行,或临时调整 kernel.yama.ptrace_scope;日常堆观测直接用 jcmd GC.heap_info + jstat -gcutil,堆转储用 jcmd GC.heap_dump,均不走 ptrace。

Q5:jps 回显里没有 Bootstrap,但页面能打开?

jps 默认只列当前用户可 attach 的 JVM。用 ps -ef | grep [j]ava(8.2)确认进程真实存在与其属主,再用同属主账号执行 jps;跨 JDK 安装(系统装了多个 JDK)时,jps 只发现「与自己同 JDK 且同 UID」的进程。

十二、参考链接

  1. 本专栏姊妹篇:《CAT 监控 3.1.0 介绍与选型指南》、《CAT 监控 3.1.0 安装指南》、《CAT 监控 3.1.0 配置参数详解》
  2. 官方仓库与源码(tag 3.1.0):https://github.com/dianping/Cat
  3. 官方服务端部署文档(Wiki readme_server):https://github.com/dianping/cat/wiki/readme_server
  4. 建库脚本(源码内):https://github.com/dianping/Cat/blob/master/script/CatApplication.sql
  5. Apache Tomcat 9 官方文档(脚本与 setenv 机制):https://tomcat.apache.org/tomcat-9.0-doc/
  6. JDK 8 jcmd/jps/jstat/jstack 工具参考:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/