线程池的并发事故

问题描述

在某个websocket的接口中,我们发现客户端在连接数超过16个时,一次业务处理的速度变得非常慢,完全不符合性能要求。

业务组成

在该接口中,接收的数据主要由两部分组成:业务功能和日志记录功能。其中,日志记录功能是由单独的线程池完成的。

问题定位

  1. 我们首先定位了问题出现的场景,一共有16个客户端同时连接了服务端,且客户端每秒向服务端发送了100次数据。
  2. 在复现该问题后,我们查看了服务端的监控,发现CPU和内存消耗很低,初步看来不是资源的问题。
  3. 为了排除资源的影响因素,我们首先调大了资源,发现该问题并没有好转,可以完全排除资源问题。
  4. 我们开始查看日志,发现日志中websocket使用的是Tomcat的默认线程,我们调整了tomcat线程池的配置,效果有所提升,但是并未彻底解决问题。
  5. 到此时,我们开始怀疑是否是代码有问题,我们先review了业务代码,业务代码中并未有问题。
  6. 然后我们review了日志相关的代码,仍然没有发现问题。
  7. 最后我们只能使用排除法,我们先注释掉了日志代码,然后发现速度一下子就提升上来了,完全能够满足我们的性能要求。

此时,我们终于找到了问题所在:

  • 日志记录中有一个特别耗时的操作;
  • 线程池的队列数量配置得很低,线程池的拒绝策略是在线程池已满,队列数量已满的情况下放到调用线程执行。

于是,在客户端发送的数据条数特别多的情况下,线程池不能很好的迅速的处理日志记录功能,日志处理的耗时操作回到了调用线程处理,阻塞了主线程的执行。

处理方案

临时方案:先根据现有资源情况,调高了队列的长度;
长期方案:
方案一:优化日志记录中的耗时操作;
方案二:采用削锋的方式来进行耗时操作。

经验教训

  1. 慎重使用线程池处理耗时操作,特别是线程池的拒绝策略为放到调用线程处理时;
  2. 在高并发的情况,慎重使用多线程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值