1. 现状·问题

你还记得你排查jar冲突的付出么?

为了有效控制jar包更新带来的未知jar引入和变动,我们经常使用dependency-tree来查看依赖关系排查问题,通常是出现问题再被动分析和排查,此时人力成本是巨大的,同时系统已出问题,没有后悔药。

2. 分析原因

jar包依赖是异变的,且隐形的,jar冲突导致的问题经常发生,研发无法每次都关注其变化。

3. 采取措施

采用“敏捷”思想,小步走,每天定时监控jar包依赖关系的变化,让风险前置,主动显现出未知的问题。

技术解决问题,CI/CD能力降低研发成本,每天23:00定时自动执行,All研发每天关注 jar doc change ~

—— 我们将依赖树作为文件进行git版本控制,同时维护到CI上自动管控jar依赖关系的变更,这样可以即时发现依赖关系的变动。流水线定时每日触发扫描依赖树,保证每日最新,发现有变动即时发起doc变更,当研发关注到mr后,可以查看前一日是who改动了what,有效管理jar包。

4. 实践步骤

4.1 创建Makefile文件

根目录:doc/dependency-tree.txt 空文件

Makefile

dependency-tree:
@mvn clean -U package -Dmaven.test.skip=true dependency:tree -Dverbose -DoutputFile=target/dependency-tree.txt --settings settings.xml
@grep -v 'omitted for' wms-outbound-web/target/dependency-tree.txt | grep -vw "tests" | grep -vw "test" | sed -e 's/TEST-SNAPSHOT/SNAPSHOT/g' > doc/dependency-tree.txt
@git add doc/dependency-tree.txt
@git commit -m "fix: [CI make dependency-tree]依赖树变更"
@git push origin HEAD:master

settings.xml

<?xml version="1.0" encoding="UTF-8"?>
<settings
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"
xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<localRepository>./maven/repository</localRepository>
<profiles>
<profile>
<id>Repository</id>
<repositories>
<repository>
<id>nexus</id>
<name>local private nexus</name>
<url>***</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>libs-releases</name>
<url>***</url>
</repository>
<repository>
<snapshots>
<updatePolicy>always</updatePolicy>
</snapshots>
<id>snapshots</id>
<name>libs-snapshots</name>
<url>***</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>***</activeProfile>
</activeProfiles>
</settings>

4.2 修改gitignore文件

  • gitignore添加内容
/maven

4.3 配置bamboo

选择定时触发的流水线(master流水线)配置

在「下载代码」原子和「Maven构建」原子中间增加原子:「自定义脚本」(必须此顺序)

Shell代码块:

cd ${globalParams.system.APP_IDENTIFIER}
make
  • 流程控制选择:失败继续(原因:CI修改代码需要mr评审,所以评审机制会导致push失败,无碍)

4.4 配置coding

增加xn_testdev_ci账号 master权限,同时增加到保护分支列表权限中

5. 实现效果

5.1 bamboo日志

运行完毕可以看到日志success,push发起评审即可

5.2 coding MR记录

可以查看到bamboo账号「测试开发_持续集成」发起的mr,评审即可(只改动依赖树文件)

6. 效能提升

2021/10/19~至今,此实践 发现42次依赖变动,其中7次发现了代码问题(研发已即时处理,否则每次未知的依赖变动都对应 >1 的研发成本)

效能量化 模拟:2021/10/19~至今

提效前(/人天) 提效后(/人天)
出现jar包冲突问题第1次 2(今日发现,问题jar已引入半年之久,人力排查成本代价巨大) 0.1(已前置发现异常并处理,早期成本代价极低,此冲突被避免)
出现jar包冲突问题第2次 2.5(明日发现,需要mvn依赖树一一排查,发现jar引入更早,成本更大) 0.5(即时出现冲突,分析doc的git history直接定位引入变动)
出现jar包冲突问题第3次 3(多日后发现,问题jar已无法溯源引入时机,依赖关系混乱,只能研发互相询问,回忆) 0.5(同上,doc git history定位引入变动)
...... ...... ......
出现jar包冲突问题n次以上,总成本计算 >2*n <0.5*n

7. 简要总结

【jar包冲突】是每个code repo和每位研发的难题 !

  • 如果我们「可以将问题避免、可以将风险前置」,那后期「维护成本必然是降低的,日常效能必然是提升的」
  • 利用CI/CD机制,将jar包依赖树作为doc文件管控到git中,将每一次变动都记录快照,按照“敏捷”思想拆解迭代(周期是每天23:00定时)自动扫描依赖关系,最早发现最早处理,别再被动了,主动出击吧!

作者:京东物流 周奕儒

来源:京东云开发者社区 自猿其说Tech 转载请注明出处

利用CI机制管控jar依赖树的更多相关文章

  1. Maven 依赖树的解析规则

    对于 Java 开发工程师来说,Maven 是依赖管理和代码构建的标准.遵循「约定大于配置」理念.Maven 是 Java 开发工程师日常使用的工具,本篇文章简要介绍一下 Maven 的依赖树解析. ...

  2. 【java】 linux下利用nohup后台运行jar文件包程序

    Linux 运行jar包命令如下: 方式一: java -jar XXX.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 ...

  3. Redis 利用锁机制来防止缓存过期产生的惊群现象-转载自 http://my.oschina.net/u/1156660/blog/360552

    首先,所谓的缓存过期引起的“惊群”现象是指,在大并发情况下,我们通常会用缓存来给数据库分压,但是会有这么一种情况发生,那就是在一定时间 内生成大量的缓存,然后当缓存到期之后又有大量的缓存失效,导致后端 ...

  4. android 利用反射机制获取drawable中所有的图片资源

    public List<Map<String,Object>> getGridData() { list=new ArrayList<Map<String,Obje ...

  5. 在maven中开发Spring需要的jar依赖

    在maven中开发Spring需要的jar依赖 <properties> <spring.version>4.0.6.RELEASE</spring.version> ...

  6. 浅谈利用同步机制解决Java中的线程安全问题

    我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等 ...

  7. 查看library的依赖树

    今天一同事问我如何解决包依赖重复的问题,我告诉他你可以用exclude,provide,compileOnly等关键字,他问我如何查找某个库依赖了什么,我说有一个插件,愣是想了好久没想起什么名字来,搜 ...

  8. 【转】Java利用反射机制访问私有化构造器

    Java利用反射机制访问私有化构造器 博客分类: java   我们都知道,当一个类的构造方法被设为私有的时候(private),在其他类中是无法用new来实例化一个对象的. 但是有一种方法可以把带有 ...

  9. Android利用反射机制为实体类属性赋值

    在做android项目时,有时会遇到从网络上获取json类型数据,赋值给实体类,实体类属性少可以一个一个的赋值,如果实体类有很多属性,赋值可能就要耗很长的功夫了,幸好Java给我们提供了反射机制.下面 ...

  10. java利用反射机制判断对象的属性是否为空以及获取和设置该属性的值

    1.java利用反射机制判断对象的属性是否为空: Map<String,String> validateMap = new LinkedHashMap<String, String& ...

随机推荐

  1. [SWPUCTF 2021 新生赛]PseudoProtocols

    [SWPUCTF 2021 新生赛]PseudoProtocols 一.题目 二.WP 1.打开题目,发现提示我们是否能找到hint.php,并且发现URL有参数wllm.所以我们尝试利用PHP伪协议 ...

  2. vue-router几大坑

    如今vue使用率很高,踩坑这就是很平常的了,使用了几年坑都依然没踩完,纠结呀 一.router.js配置要点 大家都知道vue 是组件化开发,页面很多路由难免, 这里是路由配置router.js 最外 ...

  3. 深入解析React DnD拖拽原理,轻松掌握拖放技巧!

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值.. 本文作者:霁明 一.背景 1.业务背景 业务中会有一些需要实现拖拽 ...

  4. gitlab docker升级报错

    背景 使用docker部署gitlab(9.5.4)后,发现合并代码有问题 日志: 看gitlab官网此问题已修复,由于上传了一批代码,又懒得重建,决定对gitlab升级 docker启动命令: do ...

  5. kafka学习笔记03消息队列的两种模式

     ①点对点模式   该种模式就是消费者会自动消费消息,消息收到之后会向消息队列进行确认收到消息,然后将该数据进行删除.  ②发布/订阅模式   可以有多个的topic,topic在英语中有主题的意思, ...

  6. 什么是hive的高级分组聚合,它的用法和注意事项以及性能分析

    hive的高级分组聚合是指在聚合时使用GROUPING SETS.CUBE和ROLLUP的分组聚合. 高级分组聚合在很多数据库类SQL中都有出现,并非hive独有,这里只说明hive中的情况. 使用高 ...

  7. 一文读懂什么是AIGC?

    目录 AIGC概念 AIGC发展历史 在早期萌芽阶段(1950s~1990s) 在沉淀累积阶段(1990s~2010s) 在快速发展阶段(2010s~至今) ChatGPT AIGC能做什么? 电子商 ...

  8. 实例讲解看nsenter带你“上帝视角”看网络

    摘要:本文重点关注进入目标进程的"网络ns"视角,即站在「容器中的进程视角」看待容器里面的网络世界,并在那个视角中执行命令. 本文分享自华为云社区<<跟唐老师学习云网络 ...

  9. 兰姆达 x AnayticDB 降本30%的数据湖最佳实践

    1. 客户介绍 上海兰姆达数据科技有限公司(简称"兰姆达数据")是一家提供卓越的数据科学软件产品和解决方案的初创高科技公司.兰姆达核心团队专注于大数据,机器学习算法和精准营销Saa ...

  10. 暗黑2能用Java开发?还能生成APP?

    最近烧哥发现个宝藏项目,竟然用Java开发了暗黑2出来. 众所周知,暗黑2是暴雪开发的一款经典游戏,距今虽有20多年,仍然有很多粉丝. 粉丝延续热情的方式有很多,一种是做Mod,比如魔电,对怪物.技能 ...