高并发环境下系统宕机案例分析

 

在性能测试的时候,当并发数达到200时触发该问题

现象表现为,load达到200左右,CPU高达100%,内存使用正常,FullGC频率为1小时一次。虽然java进程正常,jvm并未崩溃,但是系统已经拒绝服务,可视为宕机。

该问题一直持续到第二天上班时。在发现问题后,我们停止了LoadRunner,同时也停止了apache,也就是可以保证系统不再接收任何请求。

可是系统并未因此恢复正常。经分析怀疑系统存在死循环之类耗CPU的操作。

通过top shift+h shift+p  命令,查看线程情况,发现出现上百个java线程,他们各占1%的cpu。

进一步确定是代码问题造成的本次故障。

通过jstack命令打印出java线程的快照到日志文件,对日志文件进行分析,发现大多java线程的快照如下

 

"http-bio-8080-exec-2957" daemon prio=10 tid=0x09d01800 nid=0x4841 runnable [0x69fd4000]
java.lang.Thread.State: RUNNABLE
at org.apache.commons.collections.map.AbstractHashedMap.getEntry(AbstractHashedMap.java:440)
at org.apache.commons.collections.map.LRUMap.get(LRUMap.java:174)
at com.hongli.pandora.item.manager.WeightScoreComputor.compute(WeightScoreComputor.java:29)
at com.hongli.pandora.item.manager.CargoManager$2.compare(CargoManager.java:462)
at com.hongli.pandora.item.manager.CargoManager$2.compare(CargoManager.java:458)
at java.util.Arrays.mergeSort(Arrays.java:1270)


因此确定apache的LRUMap存在问题,经过对代码的分析发现,LRUMap是线程不安全的,在高并发的环境下,触发了死循环的bug。

最终通过在WeightScoreComputor中加入ReentrantReadWriteLock来手动保证线程的安全的方式解决了这一问题。


总结:高并发环境下暴露出的问题通常是由于内存泄漏,线程不安全等问题导致,除了在编码期间充分考虑这些问题外,更重要的是要进行充分的压力测试,并且对发生的问题进行合理的分析和排查,以解决问题和避免类似问题的再现。

这是一例典型的线程不安全的bug导致系统宕机的案例,再次提醒我们在编码过程中,必须时刻牢记共享变量的危险性,应尽量避免使用共享变量,在必须使用的情况下,必须保证共享变量在多线程环境下的安全性。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值