监控与告警是企业级 IMS 系统稳定运行的核心保障。一个完善的监控告警体系需要覆盖基础设施、应用服务、业务指标等多个维度,及时发现并处理问题,保障系统 7x24 小时稳定运行。
监控体系架构
监控系统采用分层架构设计:
- 指标采集层 - 收集各类监控指标数据
- 数据存储层 - 存储时序数据,如 Prometheus
- 告警引擎层 - 规则匹配、告警判定
- 通知服务层 - 多渠道告警通知
- 可视化层 - 监控面板与报表
指标采集设计
监控指标分为基础设施指标、应用指标和业务指标三类:
metrics-collector.js
// 指标定义与采集 class MetricsCollector { constructor() { this.metrics = new Map(); } // 记录计数器指标 incrementCounter(name, labels = {}) { const key = this.getKey(name, labels); const metric = this.metrics.get(key) || { type: 'counter', value: 0, labels }; metric.value += 1; this.metrics.set(key, metric); } // 记录 Gauge 指标 setGauge(name, value, labels = {}) { const key = this.getKey(name, labels); this.metrics.set(key, { type: 'gauge', value, labels }); } // 记录直方图指标 observeHistogram(name, value, labels = {}) { const key = this.getKey(name, labels); let metric = this.metrics.get(key); if (!metric) { metric = { type: 'histogram', values: [], labels }; // 定义直方图 buckets metric.buckets = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]; metric.count = 0; metric.sum = 0; this.metrics.set(key, metric); } metric.values.push(value); metric.count += 1; metric.sum += value; } getKey(name, labels) { const labelStr = Object.entries(labels).map([k, v] => `${k}=${v}`).join(','); return `${name}{${labelStr}}`; } }
核心监控指标
IMS 系统需要监控的核心指标:
ims-metrics.js
// IMS 系统核心监控指标 const IMSEvents = { // HTTP 请求指标 httpRequest: (req, res, duration) => { collector.incrementCounter('ims_http_requests_total', { method: req.method, path: req.route.path, status: res.statusCode }); collector.observeHistogram('ims_http_request_duration_seconds', duration, { method: req.method, path: req.route.path }); }, // 数据库操作指标 dbQuery: (operation, table, duration, success) => { collector.incrementCounter('ims_db_queries_total', { operation, table, status: success ? 'success' : 'error' }); collector.observeHistogram('ims_db_query_duration_seconds', duration, { operation, table }); }, // API 接口性能指标 apiCall: (apiName, duration, success) => { collector.incrementCounter('ims_api_calls_total', { api: apiName, status: success ? 'success' : 'error' }); collector.observeHistogram('ims_api_call_duration_seconds', duration, { api: apiName }); }, // 用户会话指标 userSession: (event, count = 1) => { collector.incrementCounter('ims_user_sessions_total', { event: event }, count); collector.setGauge('ims_active_sessions', sessionManager.activeCount); }, // 工作流指标 workflow: (processDefId, event, duration) => { collector.incrementCounter('ims_workflow_events_total', { process: processDefId, event: event }); if (duration) { collector.observeHistogram('ims_workflow_duration_seconds', duration, { process: processDefId, event: event }); } }, // 消息队列指标 mqMessage: (topic, action, success) => { collector.incrementCounter('ims_mq_messages_total', { topic, action: action, status: success ? 'success' : 'error' }); }, // 缓存指标 cache: (operation, key, hit) => { collector.incrementCounter('ims_cache_operations_total', { operation, result: hit ? 'hit' : 'miss' }); }, // 业务指标 - 表单提交 formSubmit: (formId, success) => { collector.incrementCounter('ims_form_submits_total', { form: formId, status: success ? 'success' : 'error' }); } };
告警规则设计
告警规则支持阈值告警、趋势告警和复合条件告警:
alert-rules.js
// 告警规则定义 const AlertRules = [ { id: 'high_error_rate', name: '错误率过高', expression: 'rate(ims_http_requests_total{status=~"5.."}[5m]) > 0.05', severity: 'critical', for: '2m', labels: { team: 'backend' }, annotations: { summary: 'HTTP 错误率超过 5%', description: '当前错误率: {{ $value }}' } }, { id: 'high_response_time', name: '响应时间过长', expression: 'histogram_quantile(0.95, rate(ims_http_request_duration_seconds_bucket[5m])) > 2', severity: 'warning', for: '5m', labels: { team: 'backend' }, annotations: { summary: 'P95 响应时间超过 2 秒' } }, { id: 'db_connection_pool_exhausted', name: '数据库连接池耗尽', expression: 'ims_db_connections_active / ims_db_connections_max > 0.9', severity: 'critical', for: '1m', labels: { team: 'dba' }, annotations: { summary: '数据库连接池使用率超过 90%' } }, { id: 'disk_space_low', name: '磁盘空间不足', expression: 'node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} < 0.1', severity: 'critical', for: '5m', labels: { team: 'ops' }, annotations: { summary: '磁盘空间剩余不足 10%' } }, { id: 'memory_leak_suspect', name: '内存泄漏嫌疑', expression: 'increase(ims_process_resident_memory_bytes[30m]) > 1073741824', severity: 'warning', for: '10m', labels: { team: 'backend' }, annotations: { summary: '30分钟内内存增长超过 1GB,可能存在内存泄漏' } }, { id: 'queue_backlog', name: '消息队列积压', expression: 'ims_mq_queue_depth > 10000', severity: 'warning', for: '5m', labels: { team: 'backend' }, annotations: { summary: '消息队列积压超过 10000 条' } } ]; // 告警规则引擎 class AlertEngine { constructor(rules) { this.rules = rules; this.activeAlerts = new Map(); this.checkInterval = 10000; // 10秒检查一次 } async start() { this.timer = setInterval(() => this.checkAllRules(), this.checkInterval); } async checkAllRules() { for (const rule of this.rules) { await this.evaluateRule(rule); } } async evaluateRule(rule) { const queryResult = await prometheus.query(rule.expression); const isFiring = queryResult.length > 0; if (isFiring) { if (!this.activeAlerts.has(rule.id)) { // 新告警 await this.triggerAlert(rule, queryResult); } else { // 告警持续,检查是否需要升级 const existingAlert = this.activeAlerts.get(rule.id); await this.checkAlertEscalation(existingAlert, queryResult); } } else { // 告警恢复 if (this.activeAlerts.has(rule.id)) { await this.resolveAlert(rule.id); } } } async triggerAlert(rule, values) { const alert = { id: rule.id, name: rule.name, severity: rule.severity, labels: rule.labels, annotations: this.interpolateAnnotations(rule.annotations, values[0]), startsAt: new Date(), fingerprint: generateFingerprint(rule) }; this.activeAlerts.set(rule.id, alert); // 发送告警通知 await AlertNotifier.notify('firing', alert); } async resolveAlert(alertId) { const alert = this.activeAlerts.get(alertId); alert.endsAt = new Date(); alert.status = 'resolved'; // 发送恢复通知 await AlertNotifier.notify('resolved', alert); this.activeAlerts.delete(alertId); } }
告警通知设计
支持多渠道告警通知,包括邮件、短信、钉钉、企业微信等:
alert-notifier.js
class AlertNotifier { constructor() { this.channels = new Map(); this.registerChannels(); } registerChannels() { // 邮件通知 this.channels.set('email', new EmailNotifier()); // 钉钉通知 this.channels.set('dingtalk', new DingTalkNotifier()); // 企业微信通知 this.channels.set('wechat', new WeChatNotifier()); // 短信通知(严重告警) this.channels.set('sms', new SMSNotifier()); // 电话通知(严重告警) this.channels.set('phone', new PhoneNotifier()); } async notify(status, alert) { // 根据告警级别选择通知渠道 const channels = this.getChannelsForAlert(alert); for (const channel of channels) { const notifier = this.channels.get(channel); if (notifier) { await notifier.send(status, alert); } } } getChannelsForAlert(alert) { const channels = ['email']; // 默认邮件 switch (alert.severity) { case 'critical': channels.push('dingtalk', 'sms', 'phone'); break; case 'warning': channels.push('dingtalk'); break; } return channels; } } // 告警聚合:避免告警风暴 class AlertAggregator { constructor() { this.groupWindow = 5 * 60 * 1000; // 5分钟 this.pendingAlerts = new Map(); } groupAlert(alert) { // 按告警类型+标签分组 const groupKey = this.getGroupKey(alert); if (!this.pendingAlerts.has(groupKey)) { this.pendingAlerts.set(groupKey, { count: 1, firstAlert: alert, lastAlert: new Date() }); return ['send', alert]; } const group = this.pendingAlerts.get(groupKey); group.count += 1; group.lastAlert = new Date(); return ['group', group]; } getGroupKey(alert) { return `${alert.name}:${JSON.stringify(alert.labels)}`; } }
告警自愈机制
对于可自动修复的问题,实现告警自愈机制:
alert-self-healing.js
// 告警自愈执行器 class AlertSelfHealing { constructor() { this.actions = new Map(); this.registerActions(); } registerActions() { // 重启服务 this.actions.set('restart_service', async (params) => { await systemControl.restart(params.serviceName); }); // 清理磁盘空间 this.actions.set('cleanup_disk', async (params) => { await diskCleaner.cleanOldLogs(params.days); await diskCleaner.cleanTempFiles(); }); // 重启数据库连接池 this.actions.set('reset_db_pool', async () => { await dbPool.reset(); }); // 刷新缓存 this.actions.set('flush_cache', async (params) => { await cacheManager.flush(params.pattern); }); // 下线问题节点(K8s) this.actions.set('drain_node', async (params) => { await k8s.drainNode(params.nodeName); await k8s.cordonNode(params.nodeName); }); } async execute(alert, actionConfig) { const action = this.actions.get(actionConfig.type); if (!action) { console.error(`Unknown action: ${actionConfig.type}`); return; } const execution = { alertId: alert.id, action: actionConfig.type, params: actionConfig.params, startTime: new Date(), status: 'running' }; try { await action(actionConfig.params); execution.status = 'success'; execution.endTime = new Date(); // 记录成功执行的恢复动作 await AlertHistory.recordRecovery(alert, execution); } catch (error) { execution.status = 'failed'; execution.error = error.message; execution.endTime = new Date(); // 发送告警通知给运维人员 await AlertNotifier.notifySelfHealingFailed(alert, execution); } } }
监控面板设计
监控面板展示系统运行状态:
- 系统概览 - CPU、内存、磁盘、网络等基础设施指标
- 应用监控 - QPS、响应时间、错误率等应用指标
- 数据库监控 - 连接数、慢查询、缓存命中率等
- 业务监控 - 活跃用户、表单提交量、流程处理量等
- 告警中心 - 当前告警、历史告警、告警统计分析
总结
完善的监控告警体系是保障 IMS 系统稳定运行的基础:
- 全面指标采集 - 覆盖基础设施、应用层、业务层
- 多维度告警 - 支持阈值、趋势、复合条件告警
- 告警聚合 - 避免告警风暴,减少运维噪音
- 多渠道通知 - 根据告警级别选择合适通知方式
- 告警自愈 - 自动处理常见问题,减少人工干预
- 可视化面板 - 直观展示系统状态,辅助运维决策