Micrometer计数器抛出ConcurrentModificationException并发修改异常
Micrometer计数统计触发ConcurrentModificationException的解决
问题重现
消息发布业务中用Micrometer做计数统计时,出现如下警告日志:
io.micrometer.shaded.reactor.core.publisher.Operators java.util.ConcurrentModificationException java.util.ConcurrentModificationException: null at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967) at io.micrometer.shaded.reactor.core.publisher.Operators.onDiscardMultiple(Operators.java:565) at io.micrometer.shaded.reactor.core.publisher.FluxBufferPredicate$BufferPredicateSubscriber.cancel(FluxBufferPredicate.java:174) at io.micrometer.shaded.reactor.core.publisher.FluxMap$MapSubscriber.cancel(FluxMap.java:160) at io.micrometer.shaded.reactor.core.publisher.FluxOnBackpressureLatest$LatestSubscriber.cancel(FluxOnBackpressureLatest.java:99) at io.micrometer.shaded.reactor.core.publisher.FluxMap$MapSubscriber.cancel(FluxMap.java:160)
根因
这是Micrometer内置的shaded Reactor库的并发bug:高并发场景下,FluxBufferPredicate的取消操作触发onDiscardMultiple方法迭代ArrayList时,其他线程同时修改该列表,触发了Java集合的快速失败机制。
修复方案
升级Micrometer版本
该问题已在Micrometer 1.10.x及后续稳定版本中修复,直接升级到最新版即可解决。临时规避(无法升级时)
- 降低高并发路径下的Micrometer计数频率,比如采用批量上报的方式,减少内部列表的修改频次
- 对计数逻辑做线程隔离,避免业务线程与统计线程并发操作同一列表
排查订阅生命周期
检查消息发布流程中是否存在并发取消统计相关Reactor订阅的情况,调整订阅管理逻辑,避免在列表迭代时触发取消操作。
内容的提问来源于stack exchange,提问作者user1555190
相关产品推荐
相关产品推荐

