
micrometer 的 counter 类型仅支持单调递增,无法直接递减;若需支持增减双向操作,应改用 gauge 或 distributionsummary 等可变指标类型。
micrometer 的 counter 类型仅支持单调递增,无法直接递减;若需支持增减双向操作,应改用 gauge 或 distributionsummary 等可变指标类型。
在 Micrometer 指标监控体系中,Counter 是一种只增不减的基础计量器(instrument),其设计初衷是统计诸如请求总数、错误发生次数等不可逆的累计事件。根据 Micrometer 官方 Javadoc 明确说明:
Counters monitor monotonically increasing values. Counters may never be reset to a lesser value.
这意味着调用 counter.increment(-1) 虽然语法合法,但不会产生实际效果——该操作被静默忽略,计数值保持不变。
✅ 正确做法:根据业务语义选择合适指标类型:
- ✅ 需要双向增减(如活跃连接数、库存余额、线程池当前活跃线程数)
使用Gauge,它能绑定一个动态可变的数值引用:
AtomicInteger activeConnections = new AtomicInteger(0);
// 注册 Gauge(自动读取当前值)
Gauge.builder("app.active.connections", activeConnections, AtomicInteger::get)
.register(meterRegistry);
// 增加/减少均有效
activeConnections.incrementAndGet(); // +1
activeConnections.decrementAndGet(); // -1(真正生效)- ✅ 需要同时记录计数与分布(如响应时长、队列长度变化)
可考虑DistributionSummary(支持record(long),值可任意正负,但语义为“观测值”而非“状态变更”):
DistributionSummary summary = DistributionSummary.builder("app.queue.size")
.description("Current queue size")
.register(meterRegistry);
summary.record(10); // 记录当前值为 10
summary.record(8); // 记录当前值为 8(体现下降)⚠️ 注意事项:
- 不要试图通过
Counter#increment(-n)实现递减——这是无效且易引发误解的设计误用; -
Gauge的值由外部变量驱动,务必确保该变量线程安全(推荐使用AtomicInteger/AtomicLong); - 若需原子性增减操作(如“+1/-1”且要求强一致性),
Gauge配合Atomic*已足够;无需额外封装同步逻辑; -
Counter仍适用于绝大多数累计场景(如http.requests.total,jvm.gc.count),请勿因误用而牺牲语义清晰性。
总结:Micrometer 的类型选择本质是语义建模——Counter 表达「发生了多少次」,Gauge 表达「当前是多少」。理解这一区分,是写出可维护、可解读监控指标的关键。

















