线程池优化实践

省流:通过线程池优化查询的业务逻辑,提高接口的效率,但需注意线程池的参数配置(阻塞队列大小,拒绝策略),避免带来其他的问题

问题背景:我们在使用系统的过程中,会遇到一些导出数据的场景,比如导出某个人最近一天的所有会议记录,以及会议的参会人信息

查询会议记录的业务逻辑

第一步 先根据用户查询查询用户的会议列

第二步 根据第一步查询出来的会议列表的会议信息,去循环查询每个会议的与会人信息

第三步 组合结果返回

业务代码(注:代码为模拟代码,并不涉及真实生产的代码)

并发为5时,请求耗时为平均在2000ms左右

并发50时,请求耗时为平均3000+ms左右

并发500时,请求耗时为平均4000+ms左右

随着并发量的上涨,查询数据的耗时越来越长,且并发为5时就已经达到2000ms左右了,耗时巨长

通过观察业务逻辑,循环查询每个会议的与会人信息的时候,并没有逻辑上的关联,也就是说,查询每个会议的与会人信息可以看作一个独立的过程,我们可以考虑用单独的线程去执行这个查询,通过并发来提高整体的效率。 改进后的流程为 第一步 先根据用户查询查询用户的会议列表 第二步 根据第一步查询出来的会议列表的会议信息,把每个会议的与会人查询提交到线程池当中去执行 第三步 组合结果返回

业务代码(注:代码为模拟代码,并不涉及真实生产的代码)
线程池参数

核心线程数为4(一般IO类型任务核心线程设为cpu * 2,计算类型任务时,核心线程设为cpu + 1,查询数据库或者访问第三方接口都数据IO类型的任务)

最大线程数设置为20

空闲线程存活时间 5分钟

任务队列大小 500

拒绝策略 直接拒绝

改进后 并发为5时,耗时为100+ms,速度得到质的提升

并发为50时,初期耗时为100ms,但是随着并发量的上升,后续的耗时逐渐开始变大 ,最大的时候为1000+ms,此时还出现阻塞队列中的任务,获取超时的问题,此时已经开始影响到了正常的业务,有部分的用户开始导出缺失的数据了

耗时增大 超时问题

并发为500时,也是同样的初期耗时较低,后续耗时变大,此时阻塞队列出现了大量超时的问题,大量用户已经开始导出空白的数据了,问题更加严重了

目前线程池出现的问题

问题一:后续耗时会变大?

问题二:阻塞队列已满,且出现大量队列中的任务超时问题,直接导致用户导出了空白的数据?

解决方案:
问题一 :耗时开始增大是正常的现象,因为当流量变大的时候,服务处理能力到最高后无法提升了,必然会有开始变慢的问题,影响不大,可通过限流或者是提醒用户稍等重试的方式较低影响
问题二 : 这个问题的本质是因为线程池参数设置得不合理

1、队列设置错误,该场景下,需要充分利用线程资源,将线程放入队列只会徒增等待的时间,导致等待队列里的任务全部超时抛出异常

2、拒绝策略设置错误,直接拒绝任务会抛出异常导致主流程中断,但此时主流程可能已经提交了部分任务,导致无效任务的提交

优化后参数

相比于之前,只修改了两个参数

1.把原来的任务队列设置为SynchronousQueue ,SynchronousQueue 是一个特殊的队列,其最大容量是1。也就是说,任何一次插入操作都必须等待一个相应的删除操作,反之亦然。如果没有相应的操作正在进行,则该线程将被阻塞,也就是说当线程池达到最大线程后,就不在接受新的任务了,解决阻塞队列内的任务超时的问题

2.拒绝策略改为CallerRunsPolicy,当阻塞队列满了,由提交任务的线程去完成执行,原来的流程中,主线程提交完任务后就阻塞等待了,浪费了主线程的线程资源,可利用主线程的资源,当阻塞队列满了,让主线程来执行当前任务,充分利用主线程的资源

执行 并发量为5时,执行耗时为100ms左右,和原来参数表现基本一致

并发量为50时,执行耗时为100+ms左右,最高也只到150ms,且没有出现任何异常

并发量为500时,执行耗时为300+ms左右,最高也只到500+ms,且没有出现任何异常

相关推荐
刘大辉在路上2 小时前
突发!!!GitLab停止为中国大陆、港澳地区提供服务,60天内需迁移账号否则将被删除
git·后端·gitlab·版本管理·源代码管理
追逐时光者4 小时前
免费、简单、直观的数据库设计工具和 SQL 生成器
后端·mysql
初晴~5 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱581365 小时前
InnoDB 的页分裂和页合并
数据库·后端
小_太_阳5 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾5 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala
星就前端叭6 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
小林coding7 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
AI理性派思考者7 小时前
【保姆教程】手把手教你在Linux系统搭建早期alpha项目cysic的验证者&证明者
后端·github·gpu