代码精简执行过程

京东云开发者
• 阅读 383

一、代码精简背景

随着业务需求的不断增加和产品的逐步完善,我们应用对应的代码库也在日益庞大,其中有用的、无用的、低频使用的、灰度验证的等各种类型的代码堆积在一起,给后续接手的同学增加了很多的维护和学习成本。有些代码逻辑缺乏文档说明,无人能看懂,更不敢随意修改。当有新需求需要改动这些代码时,大多数选择都是重新写一套,老的代码还继续保留,慢慢的系统中这种代码越来越多,代码工程也逐渐腐化起来,腐化到一定程度只能进行推倒重构。因此定期进行代码缩减,清理腐化的代码,对代码进行优化升级,提升代码工程的可维护性与可理解性,是十分有必要的。

我们后端的java代码工程一般和应用一一对应,根据应用的分层,代码工程也可以分为以下几类:领域服务中心(领域服务)、业务聚合中心(业务系统)、多能力应用(前后端未分离、定时任务、消息...)等种类。针对不同类型的代码库,我们需要深入代码进行探查,掌握代码的腐化程度以及有效代码的占比,判断是进行代码缩减还是进行代码重构。如果进行代码缩减,哪些代码可以直接清理,哪些代码可以重用优化,识别过程是个需要花费精力去认真做的。

二、代码精简步骤



代码精简执行过程



三、代码精简实施

1、静态代码检查

1)idea 自带工具检查

步骤1:通过idea 自带的工具来检查未使用的类、变量、方法。Preferences—>Analyze—>Inspections,执行:Run Inspection by Name



代码精简执行过程



步骤2:输入:unused declaration(未使用的声明)



代码精简执行过程



步骤3:输入:unused import(未使用的引用)



代码精简执行过程



步骤4:重复代码检查,专业版才能扫描,扫描之后,通过人工识别的方式,看是否能抽离公共方法



代码精简执行过程





代码精简执行过程





代码精简执行过程



使用idea自带工具检查的缺点如下

◦spring注入的参数值@value,会认为没有赋值"Field is never assigned.",参数未被赋值,被检测出来;

◦lombook的@data注解对象,会认为"All constructor usages belong to the calls chain that has no members reachable from entry points",被检测出来;

◦实体类中没有初始化new过,会认为"Constructor is never used",构造函数没有使用过,被检测出来;

◦无效代码的误判较多,识别需要要花费一定的时间;

◦重复代码检查都能检查出来,检查到以后,都需要人工进行识别,进行抽象处理;

2)使用PMD插件检查

步骤1:安装插件:IDEA通过 File > Settings > Plugins > Marketplace 搜索 “PMD”,按照提示进行安装,然后重启即可



代码精简执行过程



步骤2:配置检测规则:通过 File > Settings > Other Settings > PMD 可以打开检测规则的设置界面



代码精简执行过程



执行PMD:



代码精简执行过程



使用默认的规则的话,比较多,我们关心的是哪些代码可以精简,因此我们选择自定义规则,定义setting.xml文件,然后配置 PMD检查规则,选择setting.xml文件。



代码精简执行过程



具体文件内容如下:

<?xml version="1.0"?>
<ruleset name="myruleset"
         xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
    <description>My ruleset</description>

    <!-- 空的 catch 块:发现空的 catch 块没做任何异常处理的事,在大多数情形下,这会吞噬一些应该被处理或报告的异常 -->
    <rule ref="category/java/errorprone.xml/EmptyCatchBlock"/>
    <!-- 空的 finally 块:避免空的 finally 块 - 这些是可以删掉的 -->
    <rule ref="category/java/errorprone.xml/EmptyFinallyBlock"/>
    <!-- 空的 if 表达式:发现使用 if 进行了条件判断,但是判断之后没做任何处理 -->
    <rule ref="category/java/errorprone.xml/EmptyIfStmt"/>
    <!-- 空的初始化块:发现空的初始化块 -->
    <rule ref="category/java/errorprone.xml/EmptyInitializer"/>
    <rule ref="category/java/errorprone.xml/EmptyStatementBlock"/>
    <!-- 空的 switch 表达式:避免空的 switch 表达式 -->
    <rule ref="category/java/errorprone.xml/EmptySwitchStatements"/>
    <!-- 翻译   空的 Synchronized 块:避免空的 synchronized 块 -->
    <rule ref="category/java/errorprone.xml/EmptySynchronizedBlock"/>
    <!-- 空的 try 块:避免空的 try 块 -->
    <rule ref="category/java/errorprone.xml/EmptyTryBlock"/>
    <!-- 空的 while 表达式:发现空的 while 表达式 -->
    <rule ref="category/java/errorprone.xml/EmptyWhileStmt"/>

    <!-- 未用的常规参数 -->
<!--    <rule ref="category/java/bestpractices.xml/UnusedFormalParameter"/>-->
    <!-- 未用的本地变量 -->
    <rule ref="category/java/bestpractices.xml/UnusedLocalVariable"/>
    <!-- 未用的私有变量 -->
    <rule ref="category/java/bestpractices.xml/UnusedPrivateField"/>
    <!-- 未用的私有方法 -->
    <rule ref="category/java/bestpractices.xml/UnusedPrivateMethod"/>
    <!-- 不要引入java.lang:避免从’java.lang’包引入任何东西,它里面的类是自动引入的 -->

    <rule ref="category/java/codestyle.xml/DontImportJavaLang"/>
    <!-- 避免重复引入 -->
    <rule ref="category/java/codestyle.xml/DuplicateImports"/>
    <!-- 未使用的imports:去掉不使用的import -->
    <rule ref="category/java/bestpractices.xml/UnusedImports"/>
    <!-- 从同一个包引入:不需要从同一包引入类型 -->
    <rule ref="category/java/errorprone.xml/ImportFromSamePackage"/>
    <!-- 太多的静态引入:如果滥用静态引入特性,会使你的程序不具有可读性和可维护性,你引入的太多的静态成员污染 -->
    <rule ref="category/java/codestyle.xml/TooManyStaticImports"/>

</ruleset>

检测效果截图:



代码精简执行过程



步骤3:重复代码检查,下载pmd压缩包,运行cpdgui



代码精简执行过程



•命令行执行:/Users/zhanglu7/Downloads/pmd-bin-6.39.0/bin/run.sh cpdgui

•选择检查的文件夹目录,执行检查,GO



代码精简执行过程



使用PMD检查工具缺点如下:

•缺少无引用的public方法检查规则,目前都是私有方法的检查,公有方法检测规则需要自己实现,或者通过人工甄别的方式进行检查;

•重复代码检查需要额外使用CPD,重复代码检查都能检查出来,检查到以后,都需要人工进行识别,进行抽象处理;

3)静态代码检查结论

•建议使用PMD插件+CPD的方式进行,静态代码检查,检查包括:空逻辑控制代码块,未用的本地\私有变量、未使用的私有方法,检查出来的内容基本上都可以直接从代码库中删除。重复代码检查,使用CPD检查重复超过**行的代码,检查结果作为一个参考,帮助我们找到代码库中疑似重复的代码,然后通过人工甄别,判断该重复代码是否可以进一步抽象,抽象成公共的方法,供多处调用。

•test_code_reduce,demo工程,代码行数103行,通过pmd检查后,可删除10行左右(包括未使用的私有方法、无效引用、未使用的本地变量),占比10%左右。



代码精简执行过程



•jdo-***,线上工程,代码行数20005,通过pmd检查后,可删除400行左右(包括未使用的私有方法,未使用的私有变量、重复引入、无效引用、未使用的本地变量),占比2%左右。通过idea扫描的重复代码,需要人工甄别,抽取出公共方法。另外需要人工检查无用的public方法,以及类等,估计可以删除600行左右,占比3%,可以完成整体缩减5%的目标。



代码精简执行过程



2、动态代码检查

1)京东jacoco流水线

步骤1:配置流水线



代码精简执行过程



步骤2:行云应用添加启动参数

启动前配置:

mkdir -p /export/home/jacoco

cd /export/home/jacoco && wget "http://storage.jd.local/bpp-quality-public/code_coverage_statistics/jacoco-0.8.7-20210115.151120-42.tar.gz"

tar -xzvf /export/home/jacoco/jacoco-0.8.7-20210115.151120-42.tar.gz



代码精简执行过程



启动配置:

ip=$(/sbin/ip a | grep "inet " |grep -v "169.254.95.120" |grep -v "127.0.0.1" | awk '{print $2}' | awk -F/ '{print $1}')

export JACOCO_AGENT="-javaagent:/export/home/jacoco/jacoco-0.8.7-20210115.151120-42/lib/jacocoagent.jar=includes=*,output=tcpserver,port=8840,address='${ip}' -Xverify:none"

export CATALINA_OPTS="${JACOCO_AGENT:-} ${CATALINA_OPTS}"



代码精简执行过程



步骤3:运行流水线



代码精简执行过程



待运行一段时间后,再运行流水线,查看动态代码覆盖率



代码精简执行过程



2)动态代码检查结论

•建议使用京东jacoco流水线来进行动态代码检查,但需要进行长时间的运行才能得到一个相对精准的代码执行记录,该记录也仅供参考,代码是否可以删除,还需要人工进一步甄别。

点赞
收藏
评论区
推荐文章
LeeFJ LeeFJ
1年前
Foxnic-Web 代码生成 (9) —— 文件覆盖与扩展
之前的文档中我们曾多次提及,Foxnic的代码生成是迭代式的,当表结构变化后,需要重新生成相关的代码。例如某表增加了一个字段,那么对应的表结构元数据需要重新生成。此外,为了维护新加的字段也需要重新生成模块代码。  这个时候,如果模块代码已经被开发人员修改,默认情况下,重新生成代码会覆盖开发人员修改过的代码。为了能够反复生成大多数的模块代码Foxnic设计了一套机制,尽可将影响降到最低。
Stella981 Stella981
3年前
Phalcon7 给你足够的自由
基于Phalcon框架1.3版本开发,继承优化了DI(多个DI可以指定name)和PHQL(重新定义它为Model的底层数据操作接口,支持批量插入与修改),进一步完善Model以及Event,增加了调试模式,精简了代码。删除Volt、ODM,增加了QRcode、Captcha。下面是框架MVC工作流程:StartupProcess
前端微服务无界实践 | 京东云技术团队
随着项目的发展,前端SPA应用的规模不断加大、业务代码耦合、编译慢,导致日常的维护难度日益增加。同时前端技术的发展迅猛,导致功能扩展吃力,重构成本高,稳定性低。因此前端微服务应运而生。
同城售后系统退款业务重构心得 | 京东云技术团队
一、重构背景1.1、退款到家、小时购、天选退款有2套结构,代码逻辑混乱;其中小时购、天选部分售后单是和平生pop交互退款,部分是和售后中台交互退款;并且兼容3套逻辑;痛点:代码繁重,缺乏合理性的设计,后续迭代开发以及维护成本高,同时增加了系统的风险和不稳定
记一次线上问题引发的对 Mysql 锁机制分析 | 京东物流技术团队
背景最近双十一开门红期间组内出现了一次因Mysql死锁导致的线上问题,当时从监控可以看到数据库活跃连接数飙升,导致应用层数据库连接池被打满,后续所有请求都因获取不到连接而失败整体业务代码精简逻辑如下:@Transactionpublicvoidservic
京东云开发者 京东云开发者
9个月前
复杂SQL治理实践 | 京东物流技术团队
一、前言软件在持续的开发和维护过程中,会不断添加新功能和修复旧的缺陷,这往往伴随着代码的快速增长和复杂性的提升。若代码库没有得到良好的管理和重构,就可能积累大量的技术债务,包括不一致的设计、冗余代码、过时的库和框架以及不再使用的功能。这些因素都会导致软件结
京东云开发者 京东云开发者
8个月前
代码精简的治理方案和工具
一、前言在大型软件系统中,随着业务的发展和变迁,部分代码线上已经废弃或者出现冗余,由于种种原因没有被及时删除和治理,随之而来的是代码维护成本提升。代码精简的价值如上图所示,并由此成为服务治理的一个重要方向,在业界头部企业也有对应的治理项目,其主要思路是通过
京东云开发者 京东云开发者
7个月前
无用代码扫描组件设计
1、现状痛点系统越来越臃肿,开发过程中可能产生的无用代码增加了系统维护成本。2、设计思路2.1、静态代码扫描方案本方案解决静态代码下无调用方法扫描,通过ASTParser对静态文件进行扫描分析,获取代码块来判断调用关系。基本步骤及思路(1)载入本地磁盘项目
京东云开发者 京东云开发者
6个月前
京东秒送售后系统退款业务重构心得| 京东零售技术团队
一、重构背景1.1、退款京东秒送秒送退款有2套结构,代码逻辑混乱;其中秒送、天选部分售后单是和平生pop交互退款,部分是和售后中台交互退款;并且兼容3套逻辑;痛点:代码繁重,缺乏合理性的设计,后续迭代开发以及维护成本高,同时增加了系统的风险和不稳定性1.2
代码影响范围工具探索
祖传代码不敢随意改动,影响范围无法评估。并且组内时常有因为修改了某块代码,导致其他业务受到影响,产生bug,影响生产。2.研发提测完成后,测试进入测试后经常会向研发询问本次需求改动影响范围,以此来确定测试用例,以达到精准测试,提升整个需求的质量,缩短交付周期。那么,如何才能规避这种隐患?有没有一种工具能够协助代码研发及review人员更加精确的判断当前代码改动影响范围,有没有一种方法能够提供除了业务逻辑条件验证,针对代码作用范围,给测试人员提供精确验证链路?