性能文章>高CPU消耗,这次又是lettuce的锅>

高CPU消耗,这次又是lettuce的锅原创

249517

起源于Thread.sleep

最近在系统调优过程中遇到一个比较有意思的高CPU消耗的问题(当时CPU使用率已经到90%左右),先上图感受一下。
34248825806163af22c04f2.png

是的,就是Thread.sleep这个方法,消耗了大概34%的CPU,而且久居不下。其实第一眼看到这玩意儿我是懵的,啥玩意儿。
9563388106163b20931123.png

心里暗骂了开发xxx遍,这nm是哪个没脑子的开发sleep的时候用的纳秒,事实证明我错了(其实也是因为自己平时撸代码比较少,对lettuce不是很熟,因为当时并不知道是lettuce导致的),向我们勤勤恳恳的dev道歉,瑞思拜。

开始找“BUG”

OK,言归正传,问题还是要好好分析的。终于在线程dump中发现了突破口,找到了这个线程:
41651375666163b384594a2.png

然后通过这个线程我找到今天的主角,有请lettuce闪亮登场。
29815399796163b3fe75890.png

到这里,知道是lettuce搞的鬼,但我对lettuce并不熟啊,老老实实复习英语。
lettuce官方文档(https://lettuce.io/core/5.3.7.RELEASE/reference/index.html)

在官方文档中发现了这个:
27698118306163b6040f125.png

lettuce的延时监控功能默认是开启的,在内存dump中,也可以看到相关的属性为true:
24917442506163c4fe59a4e.png

简单介绍一下延时跟踪功能,具体参见官方文档:

  • 依赖LatencyUtils模块
  • 可以统计执行次数
  • 第一次响应的延迟(min, max, percentiles)
  • 命令执行完的延迟(min, max, percentiles)
  • 命令延迟统计可以1、按主机和端口或套接字路径区分(不区分命令),2、按命令类型(GET、SET、…)跟踪
  • 延时监控可以通过配置进行关闭,官方文档中有示例如下:
ClientResources res = DefaultClientResources
        .builder()
        .commandLatencyCollectorOptions( DefaultCommandLatencyCollectorOptions.disabled())
        .build();

RedisClient client = RedisClient.create(res);

到这边基本可以给优化建议:在非必要的情况下,直接关闭该功能。
除了这个方法,暂时想不到其他解决办法。

根据之前的描述,Time.sleep()是在LatencyUtils模块下的调用到的,为了满足自己的好奇心,直接看了一下LatencyUtils相关的源码。
源码地址:https://github.com/LatencyUtils/LatencyUtils/blob/master/src/main/java/org/LatencyUtils/SimplePauseDetector.java
可以看到默认sleep的时间是1毫秒
36301116546163c6f8f36a0.png

线程sleep为什么消耗CPU

这边说明一下,其实挂起的线程是不会消耗CPU资源的,消耗资源的是频繁的唤醒和sleep。sleep会导致线程上下文切换和额外的系统消耗,相似的其实还有LockSupport.park()。下面是sleep的demo(关于park的小伙伴可以自己整一个玩玩),感受下散热风扇的咆哮(线程数量越多,CPU消耗越多):

public class HighCPU {

    public static void main(String[] args) {
        int threadCount = 100;
        final List<Thread> list = new ArrayList<>(threadCount);
        for(int i =0; i<threadCount; i++){
            Thread thread = new Thread(()->{
                while(true){
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            thread.setName("cpuThread" + i);
            list.add(thread);
            thread.start();
        }

    }
}

打完收工,纪念第一篇正儿八经的博文。

请先登录,再评论

大佬的写作风格好统一 这配图 这内容

16月前

为你推荐

从猫蛇之战再看内核戏CPU
连续写了几天的代码,有些疲倦,吃过晚饭,换个工作方式,继续和大家聊猫蛇之战。蛇不仅丑陋,而且可能伤人害命,是邪恶的象征。猫与蛇战,代表着讨伐奸邪,是正义之战。猫与蛇战,技艺娴熟,举重若轻,叫人拍手叫绝
那些吃CPU的大户
最近沉浸在代码的世界里,处于两耳不闻窗外事的状态。今晚偶有闲暇,看了一眼任务管理器,IDLE进程的时间居然有800多小时,还有多个进程的CPU净时间达到小时级别。如下图所示,IDLE进程的CPU净时间
记一次线上服务CPU 100%的处理过程
告警正在开会,突然钉钉告警声响个不停,同时市场人员反馈客户在投诉系统登不进了,报504错误。查看钉钉上的告警信息,几台业务服务器节点全部报CPU超过告警阈值,达100%。赶紧从会上下来,SSH登录服务
又一次生产 CPU 高负载排查实践
前言前几日早上打开邮箱收到一封监控报警邮件:某某 ip 服务器 CPU 负载较高,请研发尽快排查解决,发送时间正好是凌晨。其实早在去年我也处理过类似的问题,并记录下来:《[一次生产 CPU 100%
什么会导致Java应用程序的CPU使用率飙升?
问题 无限循环的while会导致CPU使用率飙升吗?经常使用Young GC会导致CPU占用率飙升吗?具有大量线程的应用程序的CPU使用率是否较高?CPU使用率高的应用程序的线程数是多少?处于BLOC
线程说:不是我想爆炸,只怪你Nd4j没用好
一、项目介绍 web_rec_comm_ctr 背景:去年接手了一个排序服务,用于播单、声音、主播排序。接手以来处理过内存溢出问题,后面也没再出现过其他状况。但是最近该项目用于离线任务计算后,出现了问
性能优化:线程资源回收
一、问题模型服务平台的排序请求出现较多超时情况,且不定时伴随空指针异常。 二、问题发生前后的改动召回引擎扩大了召回量,导致排序请求的item数量增加了。 三、出问题的模型基于XGBoost预测的全排序
有些线程跑着跑着就不见了
前言最近接了一个业务需求,需求倒是不难,三下五除二就整理出设计方案,然后就开始代码改造。啪,很快,就完成代码改造,然后提测给测试小姐姐。小姐姐前面测试好好的,测到这个工程的时候,突然跟我反馈,你看这个