问题截图:
由于作者使用递归统计信息,刚开始这个接口运行得正常,但是上线运行一段时间后接口就出现了,如图的栈溢出错误。可以看出确实是堆栈溢出了,解决栈溢出目前只有两种方式:
第一种调大栈的大小:
-Xss 来配置栈的大小。 目前作者没有选择个方式。
第二种通过读代码减少递归层数:
- public Set
getTableParents(Set targetIds,Set parentsSet) { - List
tableDOList = tableRelationMapper.selectList(new LambdaQueryWrapper().in(LineageTableDO::getTargetId,targetIds)); - if (ObjectUtils.isNotEmpty(tableDOList)){
- Set
newTargetIds = new HashSet<>(); - //将父系id查出来,
- tableDOList.stream().forEach(s->newTargetIds.add(s.getSourceId()));
- parentsSet.addAll(newTargetIds);
- //再作为字进行二次查询
- getTableParents(newTargetIds,parentsSet);
- }
- return parentsSet;
- }
作者通过日志和阅读代码逻辑发现,每次newTargetIds 基本都是重复的,导致递归次数指数增长,于是修改成如下代码:
- public Set
getTableParents(Set targetIds,Set parentsSet) { - //System.out.println("targetIds Size =========>" + targetIds.size() + ", pSet==========>" + parentsSet.size());
- List
tableDOList = tableRelationMapper.selectList(new LambdaQueryWrapper().in(LineageTableDO::getTargetId,targetIds)); - if (ObjectUtils.isNotEmpty(tableDOList)){
- //System.out.println("childTable size ==========> " + tableDOList.size());
- Set
newTargetIds = new HashSet<>(); - //将父系id查出来,
- tableDOList.stream().forEach(s->newTargetIds.add(s.getSourceId()));
- Set
tmpSets = new HashSet<>(); - if (CollectionUtils.isNotEmpty(newTargetIds)) {
- newTargetIds.forEach(s -> {
- if (!parentsSet.contains(s)) {
- tmpSets.add(s);
- }
- });
- }
-
- if (CollectionUtils.isNotEmpty(tmpSets)) {
- parentsSet.addAll(tmpSets);
- //再作为字进行二次查询
- getTableParents(newTargetIds,parentsSet);
- }
- }
- return parentsSet;
- }
最后成功解决