scaffold-monitor 监控运维模块
模块概述
scaffold-monitor 是 Scaffold v2 平台的监控运维模块,提供服务器健康监控、JVM 运行时信息、API 指标采集、慢 SQL 捕获、指标趋势分析和告警管理功能。
模块通过三种采集机制实现全方位监控:
- Servlet Filter:拦截 HTTP 请求采集 API 指标(请求数、成功数、失败数、耗时)
- MyBatis Interceptor:拦截 SQL 执行捕获慢 SQL(超过阈值的 SQL)
- 定时调度:每 60 秒采集一次 JVM/系统指标快照(堆内存、线程、GC、CPU、磁盘)
功能列表
服务器监控
- 服务器健康信息(CPU、内存、磁盘)
- JVM 运行时信息(堆/非堆内存、线程数、GC 次数/耗时)
- 基础设施状态(数据库、Redis 连接状态)
- 指标趋势数据(堆内存/线程/GC/CPU 趋势图)
API 指标监控
- API 请求数/成功数/失败数统计
- API 平均耗时/最大耗时/最小耗时
- API Top N 排名
- 按日期统计,内存累积定时刷盘
慢 SQL 监控
- 超过阈值的 SQL 自动捕获
- 记录 SQL 文本、执行耗时、Mapper 方法
- 缓冲队列 + 定时刷盘,避免影响业务性能
- 历史慢 SQL 清理
指标快照
- 每 60 秒采集 JVM 堆内存、非堆内存、线程数、GC、CPU、磁盘使用
- 支持按指标类型查询趋势(HEAP/THREAD/GC/CPU)
- 过期快照自动清理(默认保留 30 天)
告警管理
- 告警规则 CRUD(支持阈值配置和评估条件)
- 告警记录查询
- 告警解决/处理
状态字段规范:
enabled字段遵循布尔语义:1= 启用,0= 禁用
核心组件
实体
| 实体 | 表名 | 说明 |
|---|---|---|
| MonitorAlertRule | monitor_alert_rule | 告警规则 |
| MonitorAlertRecord | monitor_alert_record | 告警记录 |
| MonitorApiMetric | monitor_api_metric | API 指标(按日期+端点聚合) |
| MonitorMetricSnapshot | monitor_metric_snapshot | 指标快照(JVM/系统指标) |
| MonitorSlowSql | monitor_slow_sql | 慢 SQL 记录 |
采集器
| 类 | 机制 | 说明 |
|---|---|---|
| ApiMetricCollector | Servlet Filter | 拦截 HTTP 请求,内存累积 API 指标,定时刷盘到 MySQL |
| SlowSqlCollector | MyBatis Interceptor | 拦截 SQL 执行,超过阈值则缓冲,定时刷盘到 MySQL |
| MetricSnapshotScheduler | @Scheduled | 每 60 秒采集 JVM/系统指标快照,每天凌晨 3 点清理过期数据 |
| MonitorCollectorRegistrar | - | 注册采集器的刷盘调度 |
服务层
| 服务 | 说明 |
|---|---|
| MonitorService | 服务器健康、JVM 信息、基础设施状态、指标趋势 |
| MetricService | API 指标查询、慢 SQL 查询、Top N 排名、数据清理 |
| AlertService | 告警规则管理、告警记录查询、告警解决 |
关键设计
SlowSqlCollector 循环依赖问题:
SlowSqlCollector 作为 MyBatis Interceptor 需要在 SqlSessionFactory 创建之前注册,而 MonitorSlowSqlRepository 依赖 SqlSessionFactory。为打破循环依赖,采用以下方案:
- SlowSqlCollector 不使用
@Component注解,而是通过MonitorInterceptorConfig的@Bean方法手动注册 - MonitorSlowSqlRepository 使用
@Lazy延迟注入到 SlowSqlCollector - 创建顺序:SlowSqlCollector(只依赖 Properties + @Lazy 代理)-> SqlSessionFactory -> Repository
配置参数
配置前缀:scaffold.monitor
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| enabled | boolean | true | 模块开关 |
| slowSqlThreshold | long | 3000 | 慢 SQL 阈值(毫秒) |
| snapshotInterval | int | 60 | 指标快照间隔(秒) |
| snapshotRetentionDays | int | 30 | 快照保留天数 |
| slowSqlRetentionDays | int | 30 | 慢 SQL 保留天数 |
| alertCheckInterval | int | 30 | 告警评估间隔(秒) |
| metricFlushInterval | int | 60 | API 指标刷盘间隔(秒) |
API 接口列表
服务器监控(/v1/monitor/server)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /health | 获取服务器健康信息 |
| GET | /jvm | 获取 JVM 运行时信息 |
| GET | /infrastructure | 获取基础设施状态(数据库/Redis 连接) |
| GET | /trend?type={t}&hours={h} | 获取指标趋势(HEAP/THREAD/GC/CPU) |
指标监控(/v1/monitor)
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /metric/api/page | 分页查询 API 指标 |
| GET | /metric/api/top?top={n}&date={d} | API 指标 Top N |
| POST | /slow-sql/page | 分页查询慢 SQL |
| POST | /slow-sql/clean?retainDays={d} | 清理历史慢 SQL |
告警管理(/v1/monitor/alert)
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /rule/create | 创建告警规则 |
| POST | /rule/update | 更新告警规则 |
| POST | /rule/delete/{id} | 删除告警规则 |
| POST | /rule/page | 分页查询告警规则 |
| GET | /rule/get/{id} | 获取告警规则详情 |
| POST | /record/page | 分页查询告警记录 |
| POST | /record/resolve/{id} | 解决告警 |
采集机制详解
API 指标采集
ApiMetricCollector 实现 jakarta.servlet.Filter,拦截所有 HTTP 请求:
- 跳过监控和文档端点(
/api/v1/monitor/、/api/doc、/api/swagger) - 记录每个请求的方法、URI、状态码、耗时
- 使用 ConcurrentHashMap 按
METHOD:URI累积到内存 - 定时(默认 60 秒)刷盘到
monitor_api_metric表 - 刷盘时按日期 + 端点合并统计(同一天同一端点的数据累加)
慢 SQL 采集
SlowSqlCollector 实现 MyBatis Interceptor,拦截 Executor.query 和 Executor.update:
- 记录 SQL 执行耗时
- 超过阈值(默认 3000ms)的 SQL 放入 ConcurrentLinkedQueue 缓冲区
- SQL 文本超过 5000 字符自动截断
- 定时刷盘到
monitor_slow_sql表
指标快照采集
MetricSnapshotScheduler 每 60 秒采集一次:
| 指标 | 来源 |
|---|---|
| heapUsed / heapMax | MemoryMXBean.heapMemoryUsage |
| nonHeapUsed | MemoryMXBean.nonHeapMemoryUsage |
| threadCount / threadPeak | ThreadMXBean |
| gcCount / gcTimeMs | GarbageCollectorMXBean |
| cpuUsage | com.sun.management.OperatingSystemMXBean.processCpuLoad |
| diskTotal / diskUsed | File.getTotalSpace / getFreeSpace |
过期数据清理
每天凌晨 3:00 自动执行:
- 清理超过
snapshotRetentionDays天的指标快照 - 清理超过
slowSqlRetentionDays天的慢 SQL 记录
使用示例
1. 查看服务器状态
GET /v1/monitor/server/health -- 服务器健康信息
GET /v1/monitor/server/jvm -- JVM 运行时信息
GET /v1/monitor/server/infrastructure -- 数据库/Redis 连接状态
2. 查看 API 指标
GET /v1/monitor/metric/api/top?top=10&date=2026-04-26 -- Top 10 API
POST /v1/monitor/metric/api/page -- 分页查询
3. 查看慢 SQL
POST /v1/monitor/slow-sql/page -- 分页查询慢 SQL
4. 配置告警
POST /v1/monitor/alert/rule/create -- 创建告警规则
POST /v1/monitor/alert/rule/page -- 查询告警规则
POST /v1/monitor/alert/record/page -- 查询告警记录
POST /v1/monitor/alert/record/resolve/{id}?remark={r} -- 解决告警
5. 查看指标趋势
GET /v1/monitor/server/trend?type=HEAP&hours=1 -- 最近 1 小时堆内存趋势
GET /v1/monitor/server/trend?type=THREAD&hours=6 -- 最近 6 小时线程趋势
GET /v1/monitor/server/trend?type=GC&hours=24 -- 最近 24 小时 GC 趋势
GET /v1/monitor/server/trend?type=CPU&hours=1 -- 最近 1 小时 CPU 趋势
注意事项
- 模块默认启用(
enabled=true),引入 scaffold-monitor 依赖即自动激活 - SlowSqlCollector 通过
@Bean + @Lazy注册,不使用@Component,这是为了避免与 SqlSessionFactory 产生循环依赖 - API 指标和慢 SQL 的采集使用内存缓冲 + 定时刷盘策略,应用异常停止时可能丢失未刷盘的数据
- API 指标采集会自动跳过监控模块自身和文档相关的端点,避免递归采集
- 指标快照采集使用 JMX API 读取 JVM 信息,CPU 使用率在容器环境中可能不准确(依赖
com.sun.management.OperatingSystemMXBean) - 告警规则评估间隔默认 30 秒,通过
alertCheckInterval配置 - 过期数据清理在每天凌晨 3:00 执行,清理过程中如有大量数据可能产生短暂数据库压力
- 状态枚举:
enabled字段(告警规则)遵循布尔语义:1= 启用,0= 禁用MonitorAlertRecord.status为多态状态机,不遵循布尔语义规范