写点什么

再不解决延迟不当,小心你的内存被打爆

发布于: 2021 年 05 月 26 日

​​​​​​​​摘要:这是在具体代码中发现的不当延迟的问题,极端情况下可能把内存打爆。


本文分享自华为云社区《线程中不当使用延迟问题》,原文作者:技术火炬手  。

背景

 

这是在具体代码中发现的不当延迟的问题,极端情况下可能把内存打爆。

 

代码 DevLicenseServiceRoaDelegateImpl.java

定义:



​使用:



signalRefreshHelp 定义



这段代码最大问题是使用延迟算法不当,在极端情况下会导致内存暴涨,严重影响服务程序的性能。

不要使用 sleep 来实现延迟


使用 sleep 实现延迟看起来非常直观,但是这个在高并发、多请求、长期运行的服务程序里必须特别小心。


这是因为衡量服务程序性能的一个非常重要的指标是 QPS,就是服务程序的处理能力,一般情况下越大越好;


服务程序的总并发能力等于每个线程的 qps;单个线程的 QPS = 1000 毫秒 / (处理一个请求的毫秒);


所以上面那个线程的 QPS <= 1000 / 10000 = 0.1 (因为线程 sleep 了 10000 毫秒)


这里的处理逻辑是错误的!也有很严重的性能隐患,不过幸好调用这个 api 请求不多,才没有导致严重问题。

 

开发者的意图是在创建一个任务后,延迟 10s 执行该任务,处理时序图如下



​假如时间点 t1 & t2 挨得很接近的话,线程在执行 job1 & job2 也是很接近。

 

但实际的情况变成:



​就算创建 job1 & job2 的时间很接近,但 job2 执行的时间会比预期多了 10s;连续提交的任务越多,越容易堆积,这些堆积的任务存放在 blocking queue,一直到处理完毕才删除;如果这类请求很多的话,很容易引起内存爆掉。

解决方案


选择合适的数据结构,默认线程池关联的队列是 LinkedBlockingQueue ,没有延迟控制,可以使用 DelayQueue



​DelayQueue 内部使用了 PriorityQueue 按时间排序;需要自己使用 Delayed 接口封装请求数据

下面是例子



测试代码,同时加入 3 个需要延迟 10s 的任务



​测试结果:



符合预期


点击关注,第一时间了解华为云新鲜技术~

发布于: 2021 年 05 月 26 日阅读数: 45
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
再不解决延迟不当,小心你的内存被打爆