你要偷偷学会排查线上CPU飙高的环境,然后吓坏全部人!
通过说明挪用链,发明这个处所是我代码中稀有据库的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。 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |