本文目录导读:

在Java中实现服务告警,一般会构建一个指标采集 → 规则判断 → 告警通知的闭环,下面从初级(代码内嵌)到中级(集成监控框架)再到高级(自定义告警引擎),给出三个不同层级的实现方案。
基础方案:代码内嵌 + 邮件/钉钉通知
适用场景:简单服务、快速验证、不想引入外部依赖。
核心实现
@Component
public class ServiceAlarm {
// 1. 定义告警阈值
private static final int ERROR_THRESHOLD = 10; // 10分钟内错误次数
private static final long TIME_WINDOW_MS = 10 * 60 * 1000L;
// 2. 使用滑动窗口存储错误时间戳
private final LinkedList<Long> errorTimeList = new LinkedList<>();
// 3. 通知方法(以钉机器人群为例)
private void sendAlarm(String message) {
// 使用 OKHttp 或 RestTemplate 发送 POST 请求到钉钉 webhook
// 示例略,具体参见钉钉/飞书/企业微信文档
System.out.println("[ALARM] " + message);
}
// 4. 核心告警判断逻辑
public void recordError() {
synchronized (errorTimeList) {
long now = System.currentTimeMillis();
// 清理超出时间窗口的旧记录
while (!errorTimeList.isEmpty()
&& now - errorTimeList.getFirst() > TIME_WINDOW_MS) {
errorTimeList.removeFirst();
}
errorTimeList.addLast(now);
// 判断是否触发告警
if (errorTimeList.size() >= ERROR_THRESHOLD) {
sendAlarm("服务异常频率过高,当前窗口内错误数:" + errorTimeList.size());
// 告警后重置计数,避免重复告警
errorTimeList.clear();
}
}
}
// 5. 在业务代码中调用
public void someBusinessMethod() {
try {
// 业务逻辑
} catch (Exception e) {
recordError(); // 记录一次错误
throw e;
}
}
}
优缺点:
- ✅ 简单、无外部依赖
- ❌ 无法持久化、不可分布式、扩展性差
进阶方案:集成 Micrometer + Prometheus + AlertManager
适用场景:微服务架构、Kubernetes 部署、需要可视化指标。
架构链路
Java App (Micrometer) → Prometheus (拉取指标) → AlertManager (告警规则) → 通知渠道
Java 端实现(Spring Boot 示例)
@RestController
public class ApiMonitorController {
private final Counter errorCounter;
private final DistributionSummary responseTimeSummary;
public ApiMonitorController(MeterRegistry meterRegistry) {
// 1. 定义计数器指标
this.errorCounter = Counter.builder("api.error.count")
.description("API错误计数")
.register(meterRegistry);
// 2. 定义响应时间分布
this.responseTimeSummary = DistributionSummary.builder("api.response.time.ms")
.baseUnit("milliseconds")
.register(meterRegistry);
}
@GetMapping("/api/test")
public String testApi() {
long start = System.currentTimeMillis();
try {
// 业务逻辑...
return "success";
} catch (Exception e) {
// 记录错误指标
errorCounter.increment();
throw e;
} finally {
responseTimeSummary.record(System.currentTimeMillis() - start);
}
}
}
Prometheus 告警规则(alert-rules.yml)
groups:
- name: api-alerts
rules:
- alert: HighApiErrorRate
expr: rate(api_error_count[5m]) > 0.1
for: 2m
labels:
severity: critical
annotations:
summary: "API错误率过高"
description: "过去5分钟错误率 {{ $value | humanizePercentage }}"
优缺点:
- ✅ 标准生产方案、可视化、可告警聚合
- ❌ 学习成本稍高、需要部署 Prometheus + AlertManager
高级方案:自研告警引擎
适用场景:复杂告警逻辑(如组合条件、告警降噪、动态阈值)、不能用标准监控组件。
核心设计
// 1. 告警事件定义
@Data
public class AlarmEvent {
private String metricName; // 指标名,如 "cpu_usage"
private double value; // 当前值
private Map<String, String> tags; // 维度,如 ip, service
private long timestamp;
}
// 2. 告警规则(可存数据库)
@Data
public class AlarmRule {
private Long id;
private String metricName;
private String operator; // ">", "<", "=="
private double threshold; // 阈值
private int durationMinutes; // 持续时间
private boolean enableRecover; // 是否发送恢复通知
}
// 3. 告警评估器
@Component
public class AlarmEvaluator {
// 使用 Caffeine 缓存最近状态
private final Cache<String, List<Double>> metricCache = Caffeine.newBuilder()
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
public boolean evaluate(AlarmEvent event, AlarmRule rule) {
String key = rule.getMetricName() + ":" + event.getTags();
List<Double> values = metricCache.get(key, k -> new ArrayList<>());
values.add(event.getValue());
// 判断持续时间内是否一直告警
if (values.size() < rule.getDurationMinutes()) return false;
// 取最近 durationMinutes 个数据点
List<Double> recent = values.subList(
Math.max(0, values.size() - rule.getDurationMinutes()),
values.size()
);
// 规则匹配
return recent.stream().allMatch(v -> compare(v, rule.getOperator(), rule.getThreshold()));
}
private boolean compare(double v, String op, double t) {
switch (op) {
case ">": return v > t;
case "<": return v < t;
case ">=": return v >= t;
default: return false;
}
}
}
// 4. 告警分发器(策略模式)
@Component
public class AlarmDispatcher {
@Autowired
private List<AlarmNotifier> notifiers; // 注入所有通知实现
public void dispatch(AlarmEvent event) {
String message = buildMessage(event);
notifiers.forEach(n -> n.send(message));
}
}
优缺点:
- ✅ 高度灵活、可自定义一切
- ❌ 开发成本高、需要维护状态和持久化
不同场景选型建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 单体小项目、验证代码 | 方案1:代码内嵌 | 5分钟搞定,无外部依赖 |
| 标准微服务、已有监控 | 方案2:Micrometer + Prometheus | 业界标准,配套完善 |
| 复杂告警逻辑、动态规则 | 方案3:自研告警引擎 | 完全可控,适合特殊需求 |
| 不想自建、费用允许 | 外部SaaS:如 Grafana Cloud | 零运维,开箱即用 |
最佳实践建议:
- 不要过度告警:设置合理的频率限制和冷却时间
- 提供告警恢复通知:避免告警风暴后无人关闭
- 区分告警级别:Critical(立即处理)、Warning(仅通知)、Info(日志记录)
- 暴露指标端点:
/actuator/prometheus或自定义健康检查