加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 综合聚焦 > 创业热点 > 经验 > 正文

你要偷偷学会排查线上CPU飙高的情况,然后吓坏所有人!

发布时间:2021-05-27 02:53:02 所属栏目:经验 来源:互联网
导读:通过上面的堆栈信息,可以看出,占用CPU资源的线程主要是卡在JDBC底层的TCP套接字读取上。连续执行了很多次,发现很多线程都是卡在这个地方。 通过分析调用链,发现这个地方是我代码中有数据库的insert,并且使用TDDL(阿里内部的分布式数据库中间件)来创

你要偷偷学会排查线上CPU飙高的情况,然后吓坏所有人!

通过上面的堆栈信息,可以看出,占用CPU资源的线程主要是卡在JDBC底层的TCP套接字读取上。连续执行了很多次,发现很多线程都是卡在这个地方。

通过分析调用链,发现这个地方是我代码中有数据库的insert,并且使用TDDL(阿里内部的分布式数据库中间件)来创建sequence,在sequence的创建过程中需要和数据库有交互。

但是,基于对TDDL的了解,TDDL每次从数据库中查询sequence序列的时候,默认会取出1000条,缓存在本地,只有用完之后才会再从数据库获取下一个1000条序列。

按理说我们的压测QPS只有300左右,不应该这么频繁的何数据库交互才对。但是,经过多次使用Arthas的查看,发现大部分CPU都耗尽在这里。

于是开始排查代码问题。最终发现了一个很傻的问题,那就是我们的sequence创建和使用有问题:

public Long insert(T dataObject) {  

    if (dataObject.getId() == null) {  

        Long id = next();  

        dataObject.setId(id);  

    }  

    if (sqlSession.insert(getNamespace() + ".insert", dataObject) > 0) {  

        return dataObject.getId();  

    } else {  

        return null;  

    }  

}  

public Sequence sequence() {  

    return SequenceBuilder.create()  

        .name(getTableName())  

        .sequenceDao(sequenceDao)  

        .build();  

}  

/**  

 * 获取下一个主键ID  

 *  

 * @return  

 */  

protected Long next() {  

    try {  

        return sequence().nextValue();  

    } catch (SequenceException e) {  

        throw new RuntimeException(e);  

    }  

}     

是因为,我们每次insert语句都重新build了一个新的sequence,这就导致本地缓存就被丢掉了,所以每次都会去数据库中重新拉取1000条,但是只是用了一条,下一次就又重新取了1000条,周而复始。

于是,调整了代码,把Sequence实例的生成改为在应用启动时初始化一次。这样后面在获取sequence的时候,不会每次都和数据库交互,而是先查本地缓存,本地缓存的耗尽了才会再和数据库交互,获取新的sequence。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读