JaCoCo助您毁灭线上僵尸代码

发布时间:2025-05-18 02:36:51 作者:益华网络 来源:undefined 浏览量(1) 点赞(1)
摘要:来源:京东技术 导读随着需求不断迭代,业务系统的业务代码突飞猛进,在你自豪于自己的代码量产出很高时,有没有回头看看线上真正的客户使用量又有多少呢🤔?赶快利用jacoco探针深入分析一行行代码,让您看到线上功能运行最真实的一面,参照代码覆盖情况针

来源:京东技术

导读

随着需求不断迭代,业务系统的业务代码突飞猛进,在你自豪于自己的代码量产出很高时,有没有回头看看线上真正的客户使用量又有多少呢🤔?赶快利用jacoco探针深入分析一行行代码,让您看到线上功能运行最真实的一面,参照代码覆盖情况针对性下线和删除僵尸代码,提升产研效能,降低维护成本!01现状·问题在今年的敏捷团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了!

随着需求不断迭代,业务系统的业务代码突飞猛进,在你自豪于自己的代码量产出很高时,有没有回头看看线上真正的客户使用量又有多少呢?

~费事费力耗费大量人力成本~上线的功能,可能一年没人使用,如果不进行适当的下线,就会增加系统维护成本,此时就需要计划删除无用代码。但是我们怎么知道真实线上的一行行代码层面,是否真实在使用,或者真实没人用,怎么可以放心删除下线功能呢!02

分析原因

理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目标页面展示到屏幕。

实际上多数业务系统都会存在这个通病:线上僵尸代码

可能是前期产品对业务场景没有分析到位

•可能是研发期间需求功能偏离了正确方向•可能是上线后因外界因素使客户业务量下降•······03

采取措施

理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目标页面展示到屏幕。问产品经理哪些能下线?NO没人敢承诺观测 UMP接口是否有流量?NO 只知道接口维度,有流量的接口难道所有代码都有用么使用jacoco(Java Code Coverage)进行线上代码分析,对系统做瘦身。Jacoco本质上是一个测试覆盖率工具,通过ASM字节码增强技术在源代码中加入探针从而获取代码覆盖率。Jacoco主要是通过Jave agent在main函数执行之前通过指定方法在执行的代码中加入探针来记录代码是否被执行过。Java agent是Java提供的一个启动参数,有别于代理方式的动态增强和annotation processor的编译时增强,该参数通过指定路径的jar包中的premain方法将在main方法执行之前被调用增强源代码,通过实现该方法我们可以对加载的Class文件进行修改源代码增强,使用此技术的还有大部分APM工具。https://www.jacoco.org/jacoco/trunk/doc/index.html04 实践步骤理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目

4.1  依赖jacoco.ant

在工程内的pom中引入jar依赖<dependency>    <groupId>org.jacoco</groupId>    <artifactId>org.jacoco.ant</artifactId>    <version>0.8.3</version></dependency><dependency>     <groupId>org.apache.ant</groupId>     <artifactId>ant</artifactId>     <version>1.9.9</version> </dependency>

4.2  赋能Rest请求

添加一个url地址,通过ant执行dump task用于Dump Coverage文件,避免使用配置文件且同时需要运维同事帮忙操作的问题。

@RestController@RequestMapping("/coverage")public class CoverageController {    @PostMapping("dump")    @NoCheckMenuPermission    public Result<Boolean> dumpCoverageFile() {        DumpTask dumpTask = new DumpTask();        // dump文件地址        dumpTask.setDestfile(new File("/export/Data/coverage/code-cover.exec"));        // 多次dump追加形式        dumpTask.setAppend(true);        // 选一个空闲接口即可        dumpTask.setPort(8840);        // 默认本机        dumpTask.setAddress("127.0.0.1");        dumpTask.execute();        return Result.succeed(true);    }}

4.3  嵌入jacocoagent

由于jacoco需要在服务端由jacocoagent增强的jar包,为了避免需要麻烦运维同事,通过maven依赖可以发现org.jacoco.agent这个jar包中包含由jacocoagent这个包,所以通过在部署的启动脚本添加以下命令即可通过解压的方式获得该jar包!

java启动参数添加如下:存在多个javaagent时比如pfinder之类在其后添加即可。

#decompress file 解压依赖,获得jacocoagent.jar包,避免需要联系运维上传包jar -xvf $BASEDIR/lib/org.jacoco.agent-0.8.3.jar-javaagent:$BASEDIR/bin/jacocoagent.jar=includes=com.jdwl.*,output=tcpserver,port=8840,address=127.0.0.1 -Xverify:none

图1.

premain方法中可以通过Instrumention的addTransformer添加ClassFileTransformer接口的实现类,该接口中仅有一个方法如下,通过实现ClassTransformer我们可以定义自己的代码增强方法。可以使用ASM,亦可以使用javasist等高级类库。

相关实践:Diving Into Bytecode Manipulation: Creating an Audit Log With ASM and Javassist | New Reli(https://newrelic.com/blog/best-practices/java-performance-monitoring)

4.4  JDOS资源预留

资源预留/export目录自定义处理(http://help.jcd.jd.com/help/jdos_jdd/novice/)

图2.

增加配置脚本 /home/admin/clean_export.sh(脚本默认内容上增加了 && $9 != "coverage"

输出的文件路径为/export/Data/coverage/code-cover.exec

#! /bin/bashls -lh /export | awk NR >1 {print} | awk {if ($9 != "Data") print $9} | xargs -i /bin/rm -rf /export/{} > /dev/null 2>&1ls -lh /export/Data | awk NR >1 {print} | awk {if ($9 != "jdos.jd.com" && $9 != "coverage") print $9} | xargs -i /bin/rm -rf /export/Data/{} > /dev/null 2>&1

图3.

4.5  下载cover文件

/export/Data/coverage/code-cover.exec

图4.

登录堡垒机终端 cd /export/Data/coveragejdos下载文件(http://help.jcd.jd.com/help/jdos_jdd/operation_tools/terminal.html#%E7%BB%88%E7%AB%AF%E4%BE%BF%E6%8D%B7%E4%B8%8B%E8%BD%BD-%E4%B8%8A%E4%BC%A0%E6%96%87%E4%BB%B6) curl -s up.bastion.jd.com/file/up | bash

4.6  分析代码

打开idea -> run -> show coverage data选择对应的exec文件即可获取服务端的代码覆盖情况。

绿色覆盖(活跃代码)

图5.

红色未覆盖(僵尸代码)

图6.

Reference

1.JaCoCo - Documentatio(https://www.jacoco.org/jacoco/trunk/doc/index.html)

2.javaagent使用指南 - rickiyang - 博客园 (cnblogs.com)(https://www.cnblogs.com/rickiyang/p/11368932.html)

3.使用Jacoco统计服务端代码覆盖情况实践 - M104 - 博客园 (cnblogs.com)(https://www.cnblogs.com/ccoder/p/15369719.html#4946710)

4.Diving Into Bytecode Manipulation: Creating an Audit Log With ASM and Javassist | New Reli(https://newrelic.com/blog/best-practices/java-performance-monitoring)

05 效能提升理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目

5.1  需求交付效率提升

5.1.1缩短需求交付周期

因为僵尸代码删除,减少开发需求的范围,降低老代码认知成本,降低测试回归成本需求交付周期整体呈缩短趋势2023/1月落地实践,之前需求交付周期约15天,之后约12天。

图7.

5.1.2降低开发阶段停留时长

僵尸代码大量存在,研发认知需求改动点负荷很高,需要耗费大量时间成本。

2023/1月落地后,开发阶段时长缩短到 4天 以下(由 4.54 缩短至 3.11,缩短约31%),呈明显缩短趋势

图8.

5.2  人效提升

5.2.1降低研发认知负荷

删除无用僵尸代码,圈复杂度会大幅度降低,重复代码块也会降低,则研发认知负荷也会随之降低!

平均系统重复代码块数从 31 下降至 27 左右,降低了系统维护成本!

图9.

5.2.2提升人均需求吞吐量

因为减少人力认知成本,缩小需求范围,所以会直接提升需求的吞吐量!

自从2023/1月落地实践后,人均需求的吞吐量也大幅度提升,从之前 1.5 提升到 2.5 左右。

图10.

5.3  过程质量提升

5.3.1减少自动化bug数

由于存量僵尸代码减少,则整体回滚用例和场景变得精简,黄金流程也不会被僵尸代码干扰,则自动化bug数也有明显下降趋势

随着2023年1月以来的不断实践,自动化发现的bug数也逐月递减,从11个/月 -> 9个/月 -> 6个/月 -> 5个/月。

图11.

5.3.2提升单测覆盖率

自从2023年1月落地实践后,随着删除掉大量僵尸代码,整体代码总量在减少,无效代码被无情下线,同时提升了单测代码覆盖率,呈上升趋势单测行覆盖率从 51.33% -> 52.28%,提升系统质量!

图12、13.06 简要总结理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目随着需求不断迭代交付,业务代码必然不断累积,运维成本不断升高,如果线上无用功能的代码一直残留,对研发来说是巨大的累赘!对于此类代码约定俗成为 “僵尸代码”。

赶快利用jacoco探针深入分析系统的一行行代码,看到线上功能运行最真实的一面,参照代码的覆盖情况,针对性下线和删除僵尸代码,让系统瘦身,让研发减负!

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!