1.6 怎么运转项目
无论团队管理还是项目管理都需要一个运转机制。就像内燃机一样,通过内能和机械能的相互转化,驱动车轮向前、向后开动。我们常见的汽油机是活塞式内燃机,它将燃料和空气混合,在汽缸内燃烧,释放出的热能使汽缸内产生高温高压的燃气,推动活塞做功,再通过曲柄连杆将机械功输出,驱动从动机械工作。
目前,我们已经具备了气缸(平台)、活塞(度量指标)、燃料(从上到下的支持)和空气(分支策略)这些必备条件,只欠“外力点火”和“周期性柄杆驱动”这股东风。
所谓“外力点火”,就是我们主动去激发一线研发人员去发现问题,寻找问题的解决方案,联动各技术负责人寻找最优解。所以,我们启动了频繁构建实践,帮助研发人员找到解决方法。
所谓“周期性柄杆驱动”,就是我们联动技术团队从上到下,按照一定的规范和频率将内部齿轮转动起来。所以,我们通过分层会议落实技术团队代码质量保障工作。
当技术团队不再认为代码质量提升是额外任务(工作量)的时候,这些规范就可促使工程师们形成研发习惯。当这些规范经过沉淀后,研发习惯则逐步演变为工程师文化的一部分。
下面通过项目场景分析法逐步剖析,如图1-15所示。其中,业务流程和用户行为已经在上文分析完毕。接下来,我们将重点讲解实施原则和改进方法,为读者展示一幅完整的代码质量提升解决方案画卷。
图1-15 项目场景分析法
1.6.1 频繁构建,持续发现
项目启动一个月后发现,虽然我们已经将指标和代码分支策略与研发团队达成一致意见,但从每周的数据趋势图可看出,代码质量问题总数量还在呈小幅上升趋势。前两周大家还抱着一腔热血去解决问题,但随着增量代码一直新增问题,导致问题总量看起来整体变化并不大。一个月过后,大家的激情也快退却了。
于是,我们想起上文提到的研发辅助性指标,立即改变了策略,将之前的辅助性指标作为核心指标,让研发人员先解决增量问题,先把流程走起来,流程走顺了之后,再去解决存量问题。
当时,我们以为找到了“良药”,但项目运转两周后发现另外一个现象:研发人员每次提交的增量代码中问题也很多。他们遇到紧急上线情况时,不管那些坏味道问题,只要不影响业务核心逻辑,那就按时上线。这件事情也很好理解,研发人员与其延期交付,不如先将代码质量问题放一放,下次迭代再解决。
幸运的是,我们很快发现了这个问题,并深入经常出现这类问题的团队进行调研,发现一个致命问题——研发人员集中提交代码,即代码在本地积累一段时间后批量提交,并在同一时间进行合并。
这个问题为什么严重,我给大家举一个例子。假如我想减肥,于是定了一个小目标:一个月减10kg。设想一下,我能否在每天不锻炼的情况下,到月底最后一天通过一天一夜的跑步减掉10kg?答案是肯定的:不能。假如我坚持每天跑步锻炼,每天只需要减重0.33kg即可达成目标。从可实现性上看,显然第二种方式比较容易达成目标。
虽然以上案例非常不健康,但它说明一个浅显易懂的道理:做事情要天天坚持。代码质量问题的发现和解决也是,需要分配到每天去做。
这也是持续交付的一种思想:通过频繁构建,持续发现问题,每天小步解决,持续试错。有了方法论做支撑,下面我们看看如何实施吧!
1.6.2 找方法,定原则
基于当前的严峻形势,我们紧急召开了代码质量委员会,组织各部门技术负责人一起讨论了问题的严重性,达成如下两个一致性原则。
1.坚持每天构建一次流水线原则
会议达成一致意见,要求所有研发人员必须每天将在本地验证通过的代码,在下班前提交到远程分支并触发流水线构建,直至构建流水线的代码质量门禁强制校验通过,方可认为当日代码质量通过。
下面将为研发人员提供本地代码验证方法以及质量门禁检测方法。
1)每天每个开发人员对新增代码在本地进行检查并确保通过。
若你的IDE是IntelliJ IDEA,可执行如下操作。
① 一线研发人员将本地代码提交到远程Sonar服务器,并通过Sonar平台获取本地代码质量指标。我们会将详细配置步骤以及获取指标方法给到研发人员。之后,研发人员可到Sonar平台根据对应项目和分支名找到静态代码质量分析结果。
提示
配置方法可到本书的“参考资源”处扫描二维码查看。本书将提供大量真实场景案例和方法实践供读者参考。
②在IDEA中安装SonarLint插件,配置并获取远程Sonar服务器中各语言的代码检查规则,手动操作获取或者通过配置实时获取当前文件和当前项目的代码质量报告。其运行效果如图1-16所示。
图1-16 代码质量实时分析效果
2)将本地代码提交到远程分支,并通过质量门禁强制检查。
起初,我们通过Sonar平台统一配置各项目的质量门禁,并将代码检查接入GitLab流水线。如图1-17所示,当研发人员将本地代码提交后,流水线构建会自动触发;构建结束后,GitLab会发送一封邮件给到触发者。
图1-17 GitLab平台构建流水线
几个月之后,我们将实现频繁构建的这些功能落实到自运维管理平台,并基于GitLab平台的底层逻辑扩展了其他功能。之后,我们便可以进行质量门禁设置和校验检查。运行效果如图1-18所示(和图1-17是同一个执行流程)。
图1-18 自运维管理平台构建流水线
当团队养成每天至少构建一次流水线的习惯时,你还会担心他们不会每天频繁构建流水线吗?他们会慢慢发现频繁做这件事的“红利”。
2.坚持今日事今日毕原则
会议达成一致意见,要求所有研发人员必须解决当日流水线构建时出现的所有问题,方可认为当日工作完成。而效能团队作为提供解决方案的友好“供应商”,必须做好实时响应的准备,具体做法如下。
1)通过汇总的消息驱动各研发团队负责人跟进团队当日工作完成度。
各研发团队(小组)负责人在下班前,将收到平台发送的一个汇总报告消息。同时,平台将各部门的指标发送到部门负责人;而一线研发人员在下班前将被告知:当天流水线被构建了多少次,还有哪些流水线未通过。
汇报信息包含部门(团队)当天“流水线通过率”和成员的“平均构建次数”,并可超链接到平台,以便负责人进一步下钻分析哪个团队(小组)、哪个服务、哪个负责人、哪条流水线未通过(点击流水线可查看未通过的原因)。
图1-19展示了质量门禁校验未通过,导致流水线构建失败。
2)通过大屏播报,推进研发团队及时发现和解决当天积累的问题。
大家在学习精益管理时,想必都听过丰田公司的“安灯系统”。公司每个设备或工作站都装配有安灯系统,如果生产过程中发现问题,操作员(或设备)会将灯打开引起注意,使得问题得到及时处理,避免生产中断或减少问题重复发生。
这里有一个非常重要的概念是:安灯系统并不是我们理解中的叫停产线,而是在出现问题的地方“亮灯”,呼叫支持团队及时来解决问题。
我们吸收了这个理念后,对平台设计进行了思考。
图1-19 平台流水线质量门禁校验失败
我们在每个集中办公地点设置了一个大屏显示器,这个显示器一定要摆放在最显眼的地方。该显示器可显示我们的平台页面,目前功能比较简单,只能轮播各团队的流水线和代码质量情况。当团队负责的流水线执行失败且未解决的流水线总数超过5时,系统会发送一个信息给相应团队负责人,同时播报,如××团队××个流水线执行失败,请团队负责人××及时协助解决。
团队负责人或指定的小组负责人听到播报后,必须及时过来关闭播报窗口,并立刻协助团队成员解决积累的问题。
这个举措效果非常好,我们看到线下沟通现象增多,一线研发人员遇到的问题也能在团队负责人的帮助下及时得到解决。大屏显示促使各团队成员产生“比赛”心理:你们做得好,我们要做得更好。这也能够让我们始终保持活力,并保持对数据的敬畏。
不过,前期也有人反对此事,他们觉得播报会打断开发人员的工作。所以,前期需要多调节触发播报的阈值,找到一个合适的冒红灯频次,目的是想让一线研发人员遇到的问题能够及时得到解决,并不断加强此氛围。不过,对于频繁被播报的团队,我们会私下约负责人和CTO沟通。
代码质量问题如何解决、单测覆盖率如何提升等,我们将在第2章详细讲解。
若质量门禁设置合理,所有代码质量通过检查,就能够直接部署到对应环境。运维岂不是可以节省时间做更有价值的事。运维是这么想的,我们也是这么想的,这些功能的实现将在第3章详细讲解。
倘若当前研发人员能够坚持做到频繁构建,并可驾驭自运维管理平台,也知道如何解决这些问题,如何让这个流程持续运转起来?如果研发人员只能坚持一段时间或者技术负责人带着小组成员去做其他事情,代码质量提升是不是要搁置了?我们会定期组织分层会议,让这件事情持续下去。
1.6.3 分层会议,周期性运转
我们举行会议的目的是让技术团队从上到下都能够参与到代码质量治理过程中,通过3个不同层次的会议持续运营,以分层指标和解决方法分享推动CTO、部门负责人、团队负责人、一线研发人员持续关注代码生命周期中不同阶段的问题,进而落实项目(本书“参考资源”的第1章“场景案例”中提供了样例)。
1.代码质量委员会
会议的目的是让部门负责人持续关注代码架构设计、代码模式设计、代码质量问题,代码的可扩展性、可读性和规范性,并将其作为部门核心OKR,推进技术重构和代码架构评审等实践的落实,解决存量代码问题。
该会议在每周五早上10点开始,持续时间约1h,由CTO主持,我们做记录。
会议大致流程如下。
❑ 我们整理CTO和各部门负责人关注的核心指标,初步做出分析,时间约5min。
❑ 各部门负责人依次说明部门产生问题的原因、后续解决方案、何时能达标、谁牵头负责,时间约15min。
❑ 每周轮流派一位负责人针对存量代码中某一核心业务逻辑模块,进行代码设计等方面的问题总结和改进反思,时间约30min。
❑ 我们随机抽查一个项目的一个模块,针对代码设计原则和代码质量等方面的问题进行总结,时间约10min。
该会议前期由CTO主持,当部门间主要矛盾解决后便退出,交由我们主持和协调。该会议后来合并到每周的代码质量保障协调会,每次持续20min左右,可见技术团队对代码质量的重视程度。
2.代码质量治理会
会议的目的是让团队负责人重视代码质量和代码设计,交流解决方案,相互赋能,从而做到知识共享,共同提升,推进代码评审和质量门禁实践的落实。
参会对象是每周问题较多的项目所属的团队负责人,以及想了解其他组解决方法的团队负责人。
该会议每两周举行一次,一般在周五下午2点(早上部门负责人刚开完会,明确了问题,此时他们急需解决方法),持续时间约1h,由我们组织并做记录。后续各部门每隔一个季度轮流主持并做会议纪要。
会议大致流程如下。
❑ 我们整理项目问题,按照部门、团队进行问题分析。构建数据分析平台后,主持人只需打开平台页面即可直接分析,时间约10min。
❑ 各小组负责人轮流说明各团队(项目)出现问题的原因、后续解决方法、何时达标、谁牵头解决,时间约20min。
❑ 上周遇到问题比较多的小组进行解决方案分享,保证每次会议都有输出,时间约20min。
❑ 我们整理近一周各团队遇到的共性问题并分享解决思路,时间约10min。
以上流程会随着当周问题的多少、严重程度等适当调整。
3.代码质量分享会
会议目的是让一线研发人员解决各种场景下的代码质量问题,学会如何结合平台与工程实践方法提升个人的技术水平和解决问题的能力,推进研发人员落实单测等实践。
会议形式是“在线会议+飞书直播”,还可录屏后分享。
该会议不定期举行,一般在周三下午,项目前期比较频繁,后续慢慢减少,每次持续时间约40min,由我们组织。目前,我们已经积累非常多的解决方案并放到知识库中,供所有研发人员参考。持续两个OKR周期后,该会议合并到技术培训组组织的技术分享会中,不再单独召开。
会议大致流程如下。
❑ 我们整理各场景下代码质量问题的解决方法并进行分享,持续时间约20min。
❑ 各研发人员提问,我们进行答疑和讨论,持续时间约20min。
这些原则、流程和实践方法达成一致时,就形成了默认的规范,进而构成研发生态链。
1.6.4 构成生态,养成习惯
对代码生命周期中每个关键活动(见图1-20)的质量检查,相当于为进入下一个活动设置了门槛(质量关卡)。当代码通过层层筛选和把关后,我们认为这些代码是可靠的,是具有鲁棒性的。这些检查活动按照顺序依次执行下去时,便形成了技术团队研发流程;这些原则和方法整理成文时,便形成了技术团队研发规范。
图1-20 代码生命周期中的关键活动
下面介绍代码生命周期中不同的关键活动阶段的代码质量检查。
(1)代码编写阶段
该阶段的代码质量检查可自动化执行。研发人员可在IDEA上通过SonarLint实时查看代码质量问题,及时发现,及时解决。
(2)代码提交阶段
该阶段的代码质量检查可自动化执行。效能团队在GitLab上配置阿里代码检查工具P3C。代码未通过检查,将无法提交,进而无法触发流水线的构建。同时,GitLab会向代码提交者发送消息和邮件,详细描述代码哪里不符合规范,修正后可再次提交。
(3)代码评审阶段
该阶段的代码质量检查需人工执行。效能团队在GitLab上配置合并请求(Merge Request)。团队负责人必须对研发人员提交的代码进行评审,评审通过后方可合并并触发流水线的构建。
该阶段的目的是让各团队负责人关注代码设计模式、代码业务逻辑等方面的问题。
在评审之前,首先需要建立团队的技术规范和标准,让每个决策都有依据;其次需要加强流程上的管理,建立周期性的技术架构评审机制,对架构的修改进行评审,一方面规避问题,另一方面根据问题完善规范和标准。
(4)代码构建阶段
该阶段的代码质量检查可自动化执行。研发人员通过自运维管理平台频繁构建流水线,持续发现并解决代码质量、性能和规范方面的问题,将技术债解决行为日常化;明确技术规范,加强管理,通过技术债务的可视化驱动一线研发人员分布式解决问题。
同时,设置质量门禁。研发人员必须解决掉所有增量代码问题,这样构建的流水线才能被执行,进而触发不同环境的代码部署。该过程由各团队负责人指导实践和落地。
(5)代码回顾阶段
每周组织一个部门进行代码通晒,主要针对代码块问题的解决方案进行分享与分析。同时,效能团队每周随机抽查一个业务代码模块,主要从技术架构、技术框架、代码设计等方面进行分析,驱动各部门主动进行代码重构。
技术负责人在部门内部持续驱动存量代码重构时,主要考虑以下几点问题。
❑ 因认知不足或成本高而产生架构设计或代码设计差的问题。
❑ 因能力或认知不足而选择非最优技术框架的问题。
❑ 因成本高或进度慢而没有完成代码测试的问题。
随着分层会议周期性运转,以及各层级负责人把控代码质量检查成为每个研发人员的工作习惯。从此,代码质量也成为研发团队周会、站会以及日常沟通交流的话题。