代码diff服务改进方案

背景

代码diff系统,是增量静态代码扫描,增量代码覆盖率,增量接口扫描等众多基础系统的依赖方,其稳定性和性能直接影响整个工作流。随着调用量的升高,尤其是转转增量代码统计率功能成为beetle流程中的卡点,代码diff作为基础数据提供方,渐渐暴露出了性能和前期设计方案的问题。

原始实现方案的流程如下图:

代码diff服务改进方案_第1张图片

 

存在问题

1、需要将gitlab上的代码分支克隆到本地服务器(分支新建时提前预热),通过jgit的接口进行diff。但是当代码仓库比较大,在上面提到的异常流程时,仍然要clone,拉取时间长,影响接口性能。

2、在本地服务器diff,需要加锁,导致不支持同一个代码仓库的并发。

优化方案

1、空间换时间

仍然使用代码clone到本地的方案,但是按照分支维度放置代码。这样能解决不同分支间的并发问题。优点:去除了本地git锁判断过程,逻辑相对于原来改动小,实现成本小。不足:相同分支的情况下,仍然需要在平台上对jgit的代码处理逻辑加锁。锁冲突的概率和代码git pull的时间成正比。并发较高的情况下,失败和等待的时间仍然不可接受。

2、去掉jgit

使用工具java-gitlab-api,调用gitlab原生的api获取diff的差异,并发和性能都很稳定,我们采用了这个新方案。上线初期阶段表现是完全符合要求的,也在想之前的同事为什么没有采用这个方案?

新的问题

使用过程中调用方反馈,diff不准(gitlab原生接口还不准?)。经过排查发现,gitlab的接口没有忽略空格的选项。而jgit可以使用WS_IGNORE_ALL等参数,略掉空格等格式的变更。业务方需要忽略掉只是变更了空格和格式的内容。这样增量统计才准。

方案补:

经过一番调研之后,我们发现gitlab的diff接口是没有额外的参数的。所以我们决定在gitlab的diff结果上,增加一个对比补偿方案。并且希望处理结果尽量和jgit处理结果一致。经过调研和多次尝试,最终确认使用开源工具java-diff-utils对gitlab返回的数据格式进行预处理,同时使用和jgit同样的diff算法HistogramDiff来保证数据的一致性。

其他问题:

1、使用过程中发现部分大文件获取差异内容为diff为空。原因是触发了Gitlab Diff数据大小限制。参考 Diff limits administration | GitLab 修改。

2、上面的方案,在diff文件量很大的时候,会触发性能问题,使用多线程处理。

总结

在使用gitlab api的方案过程中,我们进行了很多的尝试,走了很多的弯路,最终达到现在的效果。保证作为基础中的基础系统--diff系统的稳定和性能。各位朋友如果有其他的方案和思路欢迎在评论区留言,咱们一起交流下。

参考资料

1,https://github.com/java-diff-utils/java-diff-utils
2,https://docs.gitlab.com/ee/api/

作者:王悦

转转研发中心及业界小伙伴们的技术学习交流平台,定期分享一线的实战经验及业界前沿的技术话题。

关注公众号「转转技术」(综合性)、「大转转FE」(专注于FE)、「转转QA」(专注于QA),更多干货实践,欢迎交流分享~

你可能感兴趣的:(测试工具)