当前位置: 首页 > wzjs >正文

做包装的网站北京公司摇号

做包装的网站,北京公司摇号,建设婚介网站,网站设置关于我们怎么做事故现象 某线上服务共100台容器,第二天上午流量高峰期部分容器(约10%)cpu飙升,升至100%。 部分堆栈信息 堆栈信息如下如所示: 当前线程堆栈显示在JsonContext.get方法中调用computeIfAbsent,其Lambda表…

事故现象

某线上服务共100台容器,第二天上午流量高峰期部分容器(约10%)cpu飙升,升至100%。

部分堆栈信息

堆栈信息如下如所示:

当前线程堆栈显示在JsonContext.get方法中调用computeIfAbsent,其Lambda表达式(JsonContext$$Lambda$1329)内部触发了Program.processScript.eval,最终再次调用JsonContext.get,形成递归。

直接原因:Java 8的ConcurrentHashMap.computeIfAbsent在计算函数中重入同一键会导致死锁,因为内部锁不可重入

可以看到当前线程虽然是RUNNABLE 状态,但当前线程自身因递归调用导致锁无法释放,属于自死锁,无其他线程介入。

原因分析

ConcurrentHashMap 的锁机制

  • computeIfAbsent 在计算过程中会对当前键的哈希桶(bin)加锁(使用 synchronized 或 CAS 操作)。

  • 当计算函数内部再次尝试操作同一键时:

    • 外层操作已持有该键的锁。

    • 内层操作尝试获取同一锁 → 锁重入被禁止 → 线程阻塞。

与 HashMap 的区别

  • 普通 HashMap 允许重入,但可能引发无限递归(导致 StackOverflowError)。

  • ConcurrentHashMap 为保障线程安全,禁止这种重入行为。

在 ConcurrentHashMap 的源码中,computeIfAbsent 的关键逻辑如下:

if (bin != null) {synchronized (bin) {  // 对哈希桶加锁if (mappingFunction.apply(key) != null) {// 计算过程中再次尝试操作同一键会导致死锁}}
}
  • 锁粒度:以哈希桶(链表或红黑树节点)为单位加锁。

  • 重入限制:同一线程无法重复获取同一锁。

流量因素

由于触发重入锁的请求量较少,少于容器数量,且均在前一天晚上,流量处于低峰期,当时并没有关注cpu波动。流量高峰期时,卡住的容器请求数量增多,导致cpu飙升。此时分析堆栈文件已经有270+线程处于TIME_WAITING状态。

 

"JSF-BZ-22001-29-T-60" #11213 daemon prio=5 os_prio=0 tid=0x00007f0e10012000 nid=0x25e35 runnable [0x00007f07a6d11000]java.lang.Thread.State: TIMED_WAITING (parking)at sun.misc.Unsafe.park(Native Method)at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338)at com.lmax.disruptor.MultiProducerSequencer.next(MultiProducerSequencer.java:136)at com.lmax.disruptor.MultiProducerSequencer.next(MultiProducerSequencer.java:105)at com.lmax.disruptor.RingBuffer.next(RingBuffer.java:263)at com.engine.disruptor.publisher.ObservedPublisher.publish(ObservedPublisher.java:20)at com.engine.RuleEngine.processRule(RuleEngine.java:81)at com.engine.RuleEngine.processRules(RuleEngine.java:67)at com.engine.RuleEngine.eval(RuleEngine.java:55)at com.engine.RuleEngine$eval.call(Unknown Source)at com.api.strategy.pre.BeforePDPStrategy.eval(script17477914260641953553839.groovy:108)at sun.reflect.GeneratedMethodAccessor3436.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:43)at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:190)at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:58)at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:168)at com.api.strategy.pre.BeforePDPStrategy.execReq(script17477914260641953553839.groovy:37)at com.rule.engine.GroovyRuleEngine.exec(GroovyRuleEngine.java:27)at com.service.core.strategy.PreStrategyExecutor.handle(PreStrategyExecutor.java:112)at com.service.core.baseCore.FilterService.filter(FilterService.java:66)at com.api.PdpSecurityFilterService.filter(PdpSecurityFilterService.java:46)at sun.reflect.GeneratedMethodAccessor2550.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at com.gd.filter.ProviderInvokeFilter.reflectInvoke(ProviderInvokeFilter.java:160)at com.gd.filter.ProviderInvokeFilter.invoke(ProviderInvokeFilter.java:104)at com.gd.filter.ProviderSecurityFilter.invoke(ProviderSecurityFilter.java:42)at com.gd.filter.ProviderConcurrentsFilter.invoke(ProviderConcurrentsFilter.java:61)at com.gd.filter.ProviderTimeoutFilter.invoke(ProviderTimeoutFilter.java:37)at com.gd.filter.ProviderMethodCheckFilter.invoke(ProviderMethodCheckFilter.java:78)at com.gd.filter.ProviderInvokeLimitFilter.invoke(ProviderInvokeLimitFilter.java:57)at com.gd.filter.ProviderHttpGWFilter.invoke(ProviderHttpGWFilter.java:29)at com.gd.filter.ProviderUnitValidationFilter.invoke(ProviderUnitValidationFilter.java:30)at com.gd.filter.ProviderGenericFilter.invoke(ProviderGenericFilter.java:77)at com.gd.filter.ProviderContextFilter.invoke(ProviderContextFilter.java:54)at com.gd.filter.ProviderExceptionFilter.invoke(ProviderExceptionFilter.java:30)at com.gd.filter.SystemTimeCheckFilter.invoke(SystemTimeCheckFilter.java:79)at com.gd.filter.FilterChain.invoke(FilterChain.java:294)at com.gd.server.ProviderProxyInvoker.invoke(ProviderProxyInvoker.java:59)at com.gd.server.JSFTask.doRun(JSFTask.java:108)at com.gd.server.BaseTask.run(BaseTask.java:104)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)Locked ownable synchronizers:- <0x0000000714be3208> (a java.util.concurrent.ThreadPoolExecutor$Worker)

可以看到线程正在调用RingBuffer.next()时,因Disruptor 环形缓冲区(RingBuffer)已满,无法立即获取下一个可用的序列号(Sequence),导致线程进入短暂的等待状态(通过LockSupport.parkNanos()实现)。

Disruptor 的工作机制

  • Disruptor 是一个高性能的无锁环形队列,用于生产者和消费者之间的数据交换。
  • 生产者调用RingBuffer.next()获取下一个可写入的序列号。
  • 如果缓冲区已满(生产者速度超过消费者),生产者需要等待直到有空间可用。

代码路径

  • MultiProducerSequencer.next()的实现会检查缓冲区是否有可用空间。
  • 如果无可用空间,会调用LockSupport.parkNanos(nanos),让线程进入TIMED_WAITING状态,等待一段时间后重试(避免忙等)

TIMED_WAITING 的含义

  • 线程没有阻塞在 I/O 或同步锁上,而是通过parkNanos()主动挂起,等待条件(缓冲区空间)满足。
  • 这是一种性能优化机制,避免线程因自旋(spin-wait)浪费 CPU 资源。

这里其实是线程数增加的原因。因为obs-rule-worker- - 1是disruptor的一个消费线程,它一直自死锁,无法处理当前任务,导致RingBuffer 逻辑上已满,生产者无法申请新写入位置,生产者线程JSF-BZ-22001-29-T-XX,在RingBuffer.next()时通过LockSupport.parkNanos() 进入TIMED_WAITING 状态,接收到新的请求发现线程不够用,又新建了线程,这也就是第一个现象 线程数突增的原因。新增的线程在RingBuffer.next()时也会通过LockSupport.parkNanos() 进入TIMED_WAITING,这也就是JSF监控看到活跃线程突增后下降(下降原因:TIMED_WAITING状态的线程超时时间到期会销毁),但服务总线程数上升后保持不变的原因。


文章转载自:

http://MtZSVigV.ryqsq.cn
http://GqQgmqbq.ryqsq.cn
http://NEKVlhYg.ryqsq.cn
http://K1I9nd0a.ryqsq.cn
http://Lmx0GFfO.ryqsq.cn
http://lgSRLcZP.ryqsq.cn
http://Xx6hY8el.ryqsq.cn
http://mKWP2Ndd.ryqsq.cn
http://gwDH1Xrn.ryqsq.cn
http://PmDUVsKK.ryqsq.cn
http://tVFdBLnO.ryqsq.cn
http://oTv0Bcix.ryqsq.cn
http://hm62rgXD.ryqsq.cn
http://MuG5rSwQ.ryqsq.cn
http://UpoM0XRI.ryqsq.cn
http://gPL1zc0O.ryqsq.cn
http://NURzTJrz.ryqsq.cn
http://8MmJDtr1.ryqsq.cn
http://DI8QodUW.ryqsq.cn
http://9Pbcmfpd.ryqsq.cn
http://gR6RlZMe.ryqsq.cn
http://lGKCZAEh.ryqsq.cn
http://xwUL4goj.ryqsq.cn
http://CDSrWfMg.ryqsq.cn
http://qk4igMCF.ryqsq.cn
http://W0LYI1oR.ryqsq.cn
http://5HqUDkQ0.ryqsq.cn
http://wUt6xnUz.ryqsq.cn
http://x5hSASbv.ryqsq.cn
http://scsWy0QS.ryqsq.cn
http://www.dtcms.com/wzjs/669781.html

相关文章:

  • 常州中环互联网网站建设wordpress阿里百秀主题
  • 网站运营培训哪个网站可以做加工代理的
  • 大型网站系统解决方案网站防止机器注册
  • 菏泽做网站多少钱国内 上市网站建设公司排名
  • 四川公司网站建设招标程序员做的导航网站
  • 上海长宁网站建设南阳网站运营招聘信息
  • 淄博手机网站牛网网站建设
  • 网站制作 南通哈尔滨制作网站价格
  • 企智网络网站建设公司文学网站模板
  • 什么叫定制网站阿里云做的海外网站怎么样
  • 二手房网站建设书自己怎么做优惠卷网站
  • 电力建设工程质量监督总网站网站建设工作成果怎么写
  • 州网站建设要找嘉艺网络环球军事最新新闻
  • 做网站的边框素材群晖wordpress只能访问首页
  • 制作网站的页面设计怎么做wordpress 搜索 任意
  • 网站搭建是什么专业wordpress怎样修改字体
  • 自己建站模板wordpress编辑可以设置用户权限
  • 外贸网站建设定做网站建设在作用是什么原因
  • 创建网站要申请域名吗没有网站的域名
  • seo免费网站建设广州品牌型网站建设
  • 刷网站软件广州做淘宝的化妆品网站
  • 加拿大购物网站排名百度识别图片找图
  • WordPress调用不同主题seo人员要先对网站进行诊断
  • 广州 建网站创意网红
  • 机构组织网站建设佛山网络公司哪家便宜
  • vs 2008 建立网站自己建立公司网站的步骤
  • 西安网站搭建公司代理注册公司需要什么资料
  • 湖北智能网站建设制作浙江省城乡住房建设网站
  • 怎么制作网站域名广东建设业协会网站
  • 网站的功能和作用网站硬件需求