13 - 监控与诊断
13 - 监控与诊断
13.1 监控体系概述
13.1.1 监控层次
┌─────────────────────────────────────┐
│ 应用层监控 │
│ TPS / MSPT / 实体数 / 玩家数 │
├─────────────────────────────────────┤
│ JVM 层监控 │
│ GC 频率 / 堆内存 / 线程数 │
├─────────────────────────────────────┤
│ 系统层监控 │
│ CPU / 内存 / 磁盘 IO / 网络 │
└─────────────────────────────────────┘
13.1.2 监控工具矩阵
| 工具 | 层次 | 类型 | 说明 |
|---|---|---|---|
| Spark | 应用 + JVM | 插件 | PaperMC 最强分析工具 |
| Timings | 应用 | 内置 | Paper 内置(旧版) |
| /tps | 应用 | 内置 | 基本 TPS 查看 |
| Prometheus + Grafana | 系统 + JVM | 外部 | 完整监控面板 |
| htop / glances | 系统 | CLI | 服务器资源监控 |
| VisualVM | JVM | GUI | 内存和线程分析 |
13.2 Spark 性能分析
Spark 是 PaperMC 生态中最强大的性能分析插件。
13.2.1 安装 Spark
# 从 Hangar 下载
# https://hangar.papermc.io/lucko/Spark
# 或使用 Paper plugin.yml 自动下载
# 将 spark-paper.jar 放入 plugins/ 目录
wget -O /opt/minecraft/paper/plugins/spark-paper.jar \
"https://hangar.papermc.io/api/v1/projects/spark/versions/latest/PAPER/download"
13.2.2 TPS 和 MSPT 监控
# 查看 TPS
/spark tps
# 输出示例:
# TPS from last 1m, 5m, 15m: 20.0, 19.8, 19.5
# MSPT from last 1m, 5m, 15m: 12.5, 15.2, 18.1
# 查看详细性能信息
/spark health
# 查看实体统计
/spark healthentities
13.2.3 CPU 分析器(Profiler)
# 启动 CPU 分析(采样 60 秒)
/spark profiler --timeout 60
# 查看分析结果
/spark profiler --timeout 60 --order total
# 分析特定类型的性能
/spark profiler --timeout 300 --interval 1
分析输出示例:
--- Thread: Server Thread ---
45.2% - MinecraftServer.tick()
├── 23.1% - WorldServer.tick()
│ ├── 12.3% - Entity ticking
│ │ ├── 8.1% - Zombie.aiStep()
│ │ └── 4.2% - Creeper.aiStep()
│ └── 10.8% - Block ticking
├── 15.4% - ChunkSource ticking
└── 6.7% - Connection ticking
28.5% - idle
13.2.4 内存分析
# 查看内存使用
/spark healthmemory
# 输出示例:
# Heap Memory: 3.2 GB / 4.0 GB (80%)
# Eden Space: 1.5 GB
# Survivor Space: 128 MB
# Old Gen: 1.6 GB
# 查看对象分布
/spark gc
# 查看详细 GC 日志
/spark gcinfo
13.2.5 线程分析
# 查看线程信息
/spark threads
# 查看特定线程
/spark threadinfo "Server Thread"
13.2.6 实体和区块分析
# 实体统计
/spark healthentities
# 输出示例:
# Zombies: 245
# Skeletons: 189
# Creepers: 67
# Items: 432
# Total: 1,233
# 区块统计
/spark healthchunks
# 输出示例:
# Loaded Chunks: 3,456
# Entity Chunks: 890
# Ticket Chunks: 2,100
13.2.7 Spark Web 界面
# 启动 Spark Web 界面
/spark web
# 输出链接: https://spark.lucko.me/xxxxx
# 可以在浏览器中查看详细的性能报告
13.2.8 Spark 配置
# plugins/Spark/config.yml
# 命令权限
command-permissions:
# 是否限制命令使用
requires-permission: true
# 性能分析器设置
profiler:
# 采样间隔(毫秒)
interval: 50
# 忽略特定线程
ignore-sleeping: true
# 合并相似栈帧
merge-java-stdlib: true
# 内存分析设置
heap-analysis:
# 是否启用
enabled: true
# 分析间隔
interval: 600
# TPS 监控设置
tps:
# 精度
precision: 2
# 保留时间(分钟)
retention-minutes: 10
13.3 Timings 分析(旧版 Paper)
Paper 已移除内置 Timings,但了解它有助于分析旧服务器。
# 启动 Timings 记录
# (仅在旧版 Paper 或 Spigot 上可用)
/timings on
# 等待一段时间后
/timings paste
# 获取分析链接
# 输出: https://timings.aikar.co/?id=xxxxx
# 停止记录
/timings off
注意:新版 Paper 已完全使用 Spark 替代 Timings。如果仍在使用旧版 Timings,建议升级到 Spark。
13.4 JVM 监控
13.4.1 GC 日志
# 添加 JVM 参数启用 GC 日志
java \
-Xlog:gc*:file=logs/gc.log:time,uptime,level,tags:filecount=5,filesize=10M \
-jar paper.jar --nogui
# 分析 GC 日志
# 使用 GCViewer 工具
# https://github.com/chewiebug/GCViewer
java -jar gcviewer.jar logs/gc.log
13.4.2 VisualVM 远程监控
# 添加 JMX 远程监控参数
java \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9010 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.local.only=false \
-Djava.rmi.server.hostname=你的服务器IP \
-jar paper.jar --nogui
# 在本地电脑打开 VisualVM
# 1. 下载 VisualVM: https://visualvm.github.io/
# 2. 添加远程连接: 服务器IP:9010
# 3. 查看 CPU、内存、线程实时图表
13.4.3 JMX Prometheus 导出
# 下载 JMX Prometheus Java Agent
wget https://github.com/prometheus/jmx_exporter/releases/download/0.20.0/jmx_prometheus_javaagent-0.20.0.jar
# 创建 Prometheus 配置
cat > jmx-exporter.yml << 'EOF'
rules:
- pattern: "java.lang<type=Memory><HeapMemoryUsage>(\\w+)"
name: jvm_memory_heap_$1
type: GAUGE
- pattern: "java.lang<type=Memory><NonHeapMemoryUsage>(\\w+)"
name: jvm_memory_nonheap_$1
type: GAUGE
- pattern: "java.lang<type=GarbageCollector, name=(.+)><>(\\w+)"
name: jvm_gc_$1_$2
type: COUNTER
EOF
# 启动参数
java \
-javaagent:jmx_prometheus_javaagent-0.20.0.jar=7070:jmx-exporter.yml \
-jar paper.jar --nogui
13.5 系统监控
13.5.1 系统资源监控
# CPU、内存、进程监控
htop
# 详细系统信息
glances
# 磁盘 IO 监控
iotop
# 网络流量监控
iftop
# 系统负载
uptime
# 输出: 14:30:00 up 10 days, load average: 2.15, 1.87, 1.92
13.5.2 Prometheus + Grafana 监控
# docker-compose-monitoring.yml
services:
node-exporter:
image: prom/node-exporter
container_name: node-exporter
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
prometheus:
image: prom/prometheus
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
grafana:
image: grafana/grafana
container_name: grafana
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: admin123
volumes:
- grafana-data:/var/lib/grafana
volumes:
prometheus-data:
grafana-data:
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'minecraft'
static_configs:
- targets: ['host.docker.internal:7070']
13.5.3 Grafana Dashboard
推荐 Dashboard:
| ID | 名称 | 说明 |
|---|---|---|
| 1860 | Node Exporter Full | 系统监控 |
| 10000 | Minecraft Server | MC 专用监控 |
| 763 | Redis Dashboard | Redis 监控 |
13.6 自动告警
13.6.1 TPS 告警脚本
#!/bin/bash
# mc-alert.sh - TPS 自动告警脚本
ALERT_THRESHOLD=18.0
WEBHOOK_URL="https://your-webhook-url"
SERVER="localhost:25565"
# 使用 mcstatus 获取状态
TPS=$(docker exec mc-paper rcon-cli "spark tps" 2>/dev/null | grep -oP '20\.\d+|1\d\.\d+' | head -1)
if [ -z "$TPS" ]; then
echo "无法获取 TPS"
exit 1
fi
# 比较阈值
if (( $(echo "$TPS < $ALERT_THRESHOLD" | bc -l) )); then
echo "警告: TPS 过低 (${TPS})"
# 发送 Webhook 通知
curl -s -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "{
\"content\": \"⚠️ 服务器 TPS 过低: ${TPS} (阈值: ${ALERT_THRESHOLD})\",
\"embeds\": [{
\"title\": \"性能告警\",
\"description\": \"TPS: ${TPS}\",
\"color\": 16711680
}]
}"
fi
# 每 5 分钟检查一次
crontab -e
*/5 * * * * /opt/minecraft/scripts/mc-alert.sh >> /var/log/mc-alert.log 2>&1
13.6.2 内存告警
#!/bin/bash
# memory-alert.sh
MEMORY_USAGE=$(docker stats --no-stream --format "{{.MemPerc}}" mc-paper | tr -d '%')
if (( $(echo "$MEMORY_USAGE > 85" | bc -l) )); then
echo "警告: 内存使用率过高 (${MEMORY_USAGE}%)"
# 发送通知...
fi
13.7 性能监控仪表板
13.7.1 监控指标清单
| 指标 | 采集方式 | 告警阈值 | 说明 |
|---|---|---|---|
| TPS | Spark/RCON | < 18.0 | 核心指标 |
| MSPT | Spark/RCON | > 45ms | 每 tick 耗时 |
| 内存使用率 | JMX/Stats | > 85% | 堆内存 |
| CPU 使用率 | Node Exporter | > 80% | 系统 CPU |
| 磁盘使用率 | Node Exporter | > 90% | 存储空间 |
| 在线玩家数 | Query/RCON | - | 监控人数波动 |
| 实体数量 | Spark | > 5000 | 可能影响性能 |
| 网络带宽 | Node Exporter | > 80% | 入出站带宽 |
13.7.2 日志分析
# 分析 Paper 日志中的性能警告
grep -i "warn\|error\|tick\|lag\|overloaded" /opt/minecraft/paper/logs/latest.log
# 统计每分钟的连接/断开
grep "joined\|left" /opt/minecraft/paper/logs/latest.log | \
awk '{print $1, $2}' | cut -d: -f1,2 | sort | uniq -c
# 查看最频繁的插件错误
grep -i "exception\|error" /opt/minecraft/paper/logs/latest.log | \
grep "plugins" | awk -F'(' '{print $2}' | sort | uniq -c | sort -rn
13.8 性能基准测试
13.8.1 使用 Spark 进行基准测试
# 1. 启动分析器
/spark profiler --timeout 600
# 2. 模拟玩家活动(使用 bot 插件或手动操作)
# 3. 查看结果
/spark profiler --timeout 600 --order total
# 4. 保存报告
/spark profiler --timeout 600 --output-file benchmark.txt
13.8.2 记录性能基线
## 性能基线记录
| 日期 | 版本 | TPS | MSPT | 内存 | 实体 | 玩家 |
|------|------|-----|------|------|------|------|
| 2026-05-01 | 1.21.4 | 20.0 | 12ms | 3.2G | 1200 | 20 |
| 2026-05-10 | 1.21.4 | 19.5 | 18ms | 3.8G | 2500 | 35 |
| ... | ... | ... | ... | ... | ... | ... |
13.9 常见问题
Q1:Spark 显示 TPS 正常但玩家感觉卡?
# 可能是网络延迟而非服务器卡顿
# 使用 Spark 检查网络延迟
/spark healthping
# 检查是否有特定 chunk 导致问题
/spark healthchunks
Q2:如何找到最消耗性能的插件?
# 使用 Spark 的插件性能分析
/spark healthplugins
# 或通过 Profiler 分析
/spark profiler --timeout 120
# 查看输出中的插件相关栈帧
Q3:GC 日志如何分析?
# 简单查看 GC 频率
grep "gc" logs/gc.log | wc -l
# 查看 Full GC 次数
grep "Full GC" logs/gc.log | wc -l
# 如果 Full GC 频繁,说明内存不足或泄漏
13.10 本章小结
| 要点 | 说明 |
|---|---|
| Spark 是首选分析工具 | 免费、功能全面 |
| Profiler 定位 CPU 瓶颈 | 采样分析找出热点代码 |
| 内存分析防止 OOM | 定期检查堆使用 |
| Prometheus + Grafana 是生产监控方案 | 可视化仪表板 |
| 自动告警及时发现问题 | TPS/内存/磁盘告警 |
| 记录性能基线 | 跟踪长期性能变化 |