主干大仓也能toB,腾讯云小微不留质量后路的实战总结

公司内使用主干大仓开发的团队比较少,质疑一直不断,toB领域就更受争议,很多团队担心这担心那儿。腾讯云小微实战中,交付带宽严重不足,研发团队交付新任务的同时,还要维护大量老代码,但老代码很多时候是临时堆出来的,可维护性基本没有,团队成员为了解决一个老问题,往往要伤筋动骨好几天,这种背景下,新的交付必然受影响,为了赶交付时间,研发同学继续熬夜堆出更多的“垃圾”代码,没有时间提升技术力,同时强烈感受到产品骂娘,领导着急,苦不堪言。研发同学憋出内伤后,只好一走了之,接盘的同学继续“骗”与被“骗”,恶性循环。为了避免代码腐化和研发交付的“庞氏骗局”,腾讯云小微决定利用主干大仓将好处与坏处都放大的特点,面对质疑,不给自己留后路,从2020年3月开始在运用,很幸运,在主干大仓的逼迫下,团队进步很快,同时也拓宽了交付带宽,看到了希望。

今天分享的主要是下面几个点:

  • devops理念和方法论
  • 客户反馈处理效率提升
  • 开发效率提升实践(主干+大仓)
  • 快速定位效率提升实践(云监控+天机阁+大仓融合)
  • 快速交付效率提升实践
  • 代码设计基本原则和CR实践

1. DevOps理念

我们最基础核心的理念:可持续、自驱动、小迭代

1.1 正向循环

从开始制定Devops开始,我们围绕三步走的计划方案一一落实

其实这个问题不只我们团队有,任何一个团队都会有。

比如一个常见的场景:

客户反馈问题
产品将问题分配给开发者
开发者认为这个不是我的问题,可能是测试的原因
测试认为是产品定位的问题又推给产品
产品非常懵,又转给开发

这个看上去非常正常的流转的过程中,有个比较严正常问题就是:

流转是有时间间隔的

如果我们把流转时间加上,就非常明显了

客户反馈问题(立即)
(1 day)产品将问题分配给开发者
(1 day)开发者认为这个不是我的问题,可能是测试的原因
(1 day)测试认为是产品定位的问题又推给产品
(2 day)产品非常懵,又转给开发

最后就导致客户得到的反馈是非常长,长期以往就会损害品牌印象

一个遗憾

基于这种情况我们去请教了安灯智研这些客服体系平台,但是很遗憾的是,由于平台的种种原因,经过1个月的对接,最终也没能将这个功能打通。

2.2 Tapd的一个新功能

就在我们束手无策的情况下,我们意外在tapd上发现了一个刚上线的定时任务功能

这个功能它有什么用?就是你可以设置非常非常多的小任务,当满足什么条件时候触发,就举例子说。基于这个小功能,我们做了些客户反馈上的优化

也就是:

客户反馈问题(立即)
tapd立即拉群通知产品人员
(1h)产品将问题分配给开发者
tapd立即拉群通知开发者
(1 h)开发者认为这个不是我的问题,可能是测试的原因
tapd立即拉群通知测试人员
(1 h)测试认为是产品定位的问题又推给产品
tapd立即通知产品人员
……
如果问题超过2天未解决,我们会自动上升通知到组长层
如果问题超过1周未解决,我们会自动上升预警到总监层
如果问题超过2周未解决,我们会自动上升预警到GM层

目前我们已经在3个项目线上开始使用这个功能。

2.3 效果

我们从2020.09发现这个问题之后,原本客户反馈问题处理时间要64天,经常被投诉.

为此我们将客户反馈问题纳入到SLA体系每周过一遍,在这个措施下,我们看到客户反馈处理时长从64天逐步降到了11-14天,但是降到这个程度的时候,我们发现很难再提升了。

我们在2021年5月引入TAPD的自动任务的功能之后,2021年6月客户反馈处理时长首次突破7天下降到5. 01天。完成了上半年指定的目标!

同时到8月1日又再次下降到了 4.22天!

从下往上看,我们针对大家常用的一些监控全部进行了一个封装。

常用的存储我们也进行了一个大部分的封装。

还有大家常用的日志、通知、函数、常用组件,基本都有封装了。

在这之上就是一些公共约定了。比如公共常量、结构体、错误码、协议库和编译环境。

第二层就是一些框架层的适配了。我们现在去写trpc代码或者写taf代码,在编码层面上,大家基本上感知不到的差异的。

当我们做完这种搭建之后,我们发现就会实现非常多的利于团队的事情。

3.3.1 快速搭建环境

以前新来的员工,我们都会预留一周的时间让他搭环境。但目前的话,可能只要半个小时到一个小时。

我上次电脑自己坏了,自己试了一次,大概是十分钟就把整体的环境搭建起来了。

3.3.2 统一错误码

统一错误码其实是仿造美国航天局的维修手册。我们经常看到,空间站出了问题,宇航员手忙脚乱地拿出说明书,找到那个错误码,然后找到对应的操作,然后去把这个问题解决。

我们统一错误码,其实是想做到一个最终状态:

只要是我们云小微的一个用户,只要告诉我们一个返回码,我们就能够大概的知道到底是一个什么问题

3.3.3 统一的CI/CD

所有基于大仓的流水线是统一的。新服务只要复制别人的流水线,改其中两个参数就可以了

3.3.4 学习型组织

我认为整个开发模式给大家一个最大帮助就是,建立了一个学习型组织。

为什么说是一个学习型组织?因为我们每个人发现的问题都会在群里去反馈,然后发起的CR也会在群里去发起,然后邀请大家来CR自己代码。而不是像以前一样自己偷偷的Merge。

另外一个好处就是可以促进我们的技术栈演进,以前我们会有一个平台小组专门去推进这个大仓的组件封装,现在就是开始成员自觉将一些好用的组件封装到我们的公共库里面去。像敏感词检测、卡夫卡等组件。其它的好处就是,从单兵作战演变为群体作战,可以群策群力的去快速的战胜一些问题和解决一些问题。

100+服务案例参考,100+组件封装支持,服务开发可以规模化流程化

3.4 协作式问题

大家听我吹了这么久的一个协作式开发,有些人就会反感,大仓难道是一个包治百病的东西吗?如果是的话,为什么整个公司没推进起来,就你们这一个小部门在搞。

首先我们明晰一点就是:大仓加主干开发并不是一个银弹,而是一个代码工程实践的放大器。其实这个在km或者乐问上已经讨论过很多次。

为什么说他是个放大器,是因为:

!!#ff0000 当你大仓做的好的时候,你的优势将会无限的被放大

但是当你这个大仓做的差,那么问题也会无限的放大!!

3.5 成员反馈

从2020年3月底开始去做这个实践了。在21年3月底的时候,做过一次问卷调查,邀请了当时参与主干开发的16个同学做反馈统计,下面就是一个反馈的占比。

从新人入职到合入代码到主线,我们制定了非常严格的4道关卡

3.7.1 第一关:新人培养

首先我们新人入职,无论你是社招还是校招,进来之后我们都会做一个代码CR的一个培训:

  • 代码该怎么设计?
  • 大仓+主干怎么开发?
  • 环境如何快速搭建?
  • 团队的代码氛围快速培养
  • 有哪些代码规范?

每次大概在一个小时到两个小时之间。

3.7.2 第二关:编码检查

然后在编写代码的时候,我们的makefile里面已经集成了 golint检查和go fmt 自动格式化。只要你编译,就会提示golint检查,并且做代码自动格式化,这些都是在新人完全无感知的情况下去做的

3.7.3 第三关:PreMerge

我们在大家发起MR之后,自动开始执行不周山流水线 (我们devops小组,叫共工。所以将这种基础支撑流水线叫做不周山) ,这个不周山有哪些功能

  • 腾讯代码检查
+ 啄木鸟安全检查
+ gometalint检查
+ 圈复杂度检查
  • xcheck检查
  • 单元测试检查(doing)

3.7.4 第四关:CR

我们是强制要求CR的,至少有一个人CR通过之后,才能合入master的,而参与CR的同学都是我们核心开发骨干,我们后面也在计划针对这些核心开发骨干做一些Code ReadAbility培训,目前已经参照PCG的EPC的做法,在制定Code ReadAbility培训计划了。

一个代码合入到master,如果由于代码导致后续出了问题,我们目前鉴定是 开发人员90%责任,10%CR同学的责任。

3.7.5 代码治理成绩:

我们在2020年4月大仓项目成立之初就严格执行了 golint规范+《腾讯代码规范》,但是即便我们完全遵守了代码规范,也很难保证我们的代码就完全没问题。一年后也就是在2021年4月,我们再次加入了腾讯代码检查+xcheck检查,让我意想不到的是,当我们开启这些东西之后,原本问题数为0,竟然飙升到了1500+

很多东西我们原来并不在意,但是在深刻思考后,确实发现这些规范如果不遵守会导致代码加速腐化。于是我们就开始修复,经过三个月的修复,当前问题数已经降为了24个

何为工业级开发:

开发具有规模化、标准化、创造力

3.8.1 规模化

在规模化这一块,我认为我们已经是做的非常成熟了。

我们有统一的CI/CD流水线,你要做的就是基于模板修改3-5个参数就能完成CI/CD体系的打通

我们有统一的代码检测系统,你只要正常开发,编译,MR就能接入到完善的代码检测系统

我们有统一的编译环境,无论你用osx还是linux抑或windows,都能快速搭建编译环境进行编译发布

我们有100+的公共组件封装,99%的功能都已经封装好了,只等你去使用,这个数字,还在以每个月10+的速度增长

这些无感知的部分,恰恰是工业级开发的基础底座。设想:这些东西每个开发人员在进来的时候都是微感知甚至无感知的。举例子说配置文件,天极阁这些,开发人员不需要关心权限管理,功能分割,分组,后续的迭代升级,组件的架构原理,就能无障碍的使用起来。那是不是就可以将全部精力投入到业务开发里面去,创造更大的价值呢?

3.8.2 标准化

得益于我们规模化的应用,我们标准化也做得非常扎实

比如代码标准化,保证每个同学看到代码不会产生隔阂,如果有,就是CR做得还不够细致

比如编码标准化,应该要接入那些组件,应该要如何设计一个高效的函数架构,这些在日常CR中,都会有代码交流促进所有人快速成长

比如输出标准化,我们对日志的输出做了很多培训和讨论,如果做一个高效的日志输出也在日常CR中有体现

3.8.3 创造力

在补足规模化和标准化之后,所有的工程师就能在这之上发挥创造力。比如说:

  • 快速解决一些问题
  • 推动公共组件的一些完善
  • 还有整体的一个技术栈迭代,快速的向云原生发展靠齐。
  • 把很多局部优化的东西转变成全局优化

以上这些都是我们目前在做在演进的一个地方,而且在群策群力这一块,已经做得相当不错。

3.8.4 成果

目前腾讯云小微能够支持40+个不同KA端的特殊特性,数百种客户bot,以及8种不同功能特性的政务交通等场景的私有化发布

企点项目上,西安支撑域的开发同学,可以按照云小微代码与质量规范入仓参战,高质量的完成了功能开发以及开发之后的代码交接,间接拓展了交付带宽;

3.9 经验和教训

我们实行主干开发以来,也不是一帆风顺,下面是我们的一些经验和教训

原来TAF就自带了一个服务监控/PP监控/特性监控,随后我们发现天机阁好用,后面我们公司在主推007统一监控告警体系,所以我们也统一进行了007监控上报。

在我们接入了这么多监控告警之后,发现数据上报的冗余是比较多的,但是由于我们采用的是大仓的开发模式,目前已经收拢到云监控以及天机阁了。

目前所有的框架、存储都是走统一的云监控和天机阁的监控告警。

公司的天机阁真的挺好用,而我们部门作为一个天机阁主要贡献部门,贡献了taf-cpp,taf-go,taf-java,taf-nodejs的代码和组件封装。

同时,由于天机阁的TPS非常大(1000W/TPS),所以我们将天机阁的一些重要的模块进行了独立部署。比如图中collector,ES存储以及它的API Server都已经独立部署到云上了。这种独立部署的方式能够保证我们天机阁的稳定性,即便天机阁出线了大范围的故障和大范围的变更,我们也不会受影响。

天机阁如何使用:

我们直接在群聊里面直接就是现场抓一个SessionID的,直接去打开天机阁,就可以看到链路日志。只需要把找到的问题截个图丢到群里,然后就可以快速回复了。整个的过程的话,就四五十秒的时间就完全足够了。

关于天机阁,由于我们之前已经特意请过天机阁主负责人的tensorchen来跟我们讲解架构和功能,所以我们这里就不赘述了。

4.3 日志体系

大仓做这个日志体系真的是非常快。如下图所说,开发人员就只需要一行代码,就能无感知的接入非常庞大的日志体系

我们从发起MR到最后发布到正式环境,整体的一个流程。

大概最快的是28分钟,最慢也是在四五十分钟的样子,而大部分的时间,是耗费在其中自动观察阶段。这个阶段我们要耽误20分钟的时间去观察服务的超时率,异常率吗如果有问题还要进行自动回滚。

整个流程卷入的人员就只有两个人,第一个就是开发人员自己,第二个就是测试人员。接入的人少,无需测试,发布速度是非常敏捷的。

那有的同学会问:这个交付体系怎样去保证交付质量?毕竟你半小时左右就上生产环境了,肯定也没时间去提测了,代码质量如何保证?

有的:图中紫色的模块,就是一些质量保障的模块。除了这些模块保障意外,还有一个非常严格的免测校验。

5.2 免测前提

image.png

单从行覆盖率跟方法覆盖率来说,我们其实比腾讯广告,腾讯文档,应用宝更加严苛的,但是行覆盖率方法覆盖率我们认为说明不了什么。因为即便当我们的行覆盖率达到了90%,我们的分支覆盖率可能才30%不到。所以所有覆盖率指标中,最重要的的是分支覆盖率。而我们敢做免测发布,底气从哪里来?,把分支覆盖率做上来。

将分支覆盖率做到60%有多难?

举例子说:你写了700行单测,行覆盖率85%,但是分支覆盖率才20%左右。为了达到这个及格线,你可能需要额外补充3000行单测的代码才能做到!

除此之外,我们还要求,每次发布 行覆盖率+方法覆盖率+分支覆盖率的指标数据不能比上一次低

我们当前已经完成了58条免测流水线的建设,有58个服务,已经开始走这种绿色通道快速的对外发布服务了。

6 编码实践

编码实践我们大概实践了1年多,经过这一年多的反复CR,现在除了刚入职的同学,现在提交的代码都是非常规范了。

6.1 MR规范

image.png

1.每次提交代码不能超过200行。超过200行低于500行,别人心情好的时候可能会帮你过一下。但是你超过了500行那你就只能去找总监去CR 了

  1. 不允许提交二进制文件,这样才能才能保证仓库容量膨胀太快。二进制,doc文档等其它,统统存放到 腾讯软件源和iwiki上去。
  2. 不并行写代码。就是当你开发完一段代码,发起CR后,不要紧接着去做另一个feature开发。正确的做法是催着别人CR你的代码,然后你根据他人的CR尽快修复,合入到主分支,再从主分支拉出新的分支进行新的开发

6.2 代码设计

代码设计这个东西比较玄乎,大家可以去看看Cheaterlin的一些文章。

我这边主要重点说下面这几个点。

image.png
  1. 别打那么多日志。我们有的服务一天一个异常都没有,但是1天就有80G的debug日志打出来,造成了资源的极大浪费
    2.打关键信息,日志打了几千行,关键的一些信息都没有,打了个寂寞
    3.别用魔法数字,别用魔法字符串,用了不留注释,代码直接腐化
  2. 代码洁癖,发现看着不爽的地方就列举出来,尽快处理
  3. 主动修复,在CR之外发现问题,顺手修复掉。并且留下注释,交流心得。整个团队氛围才会好起来

6.3 代码CR实战

我们部门在CR的时候都是在CR一下什么东西,实战演习一下。

我们看下面这个代码,从12行到32行,短短20行里面可以CR出多少东西出来

image.png

CR举例:

image.png

修改后的代码:

image.png

6.4 代码规范

最后就是我们现在遵循的代码规范

image.png

7 Q&A

Q:就这大仓推进过程中,你们也不是一帆风顺的。肯定有遇到过很多坎坷,有没有记录下来,遇到过哪些问题是怎么解决的。然后我们也可以借鉴一下。

A:很遗憾我们当时在做这些事情的时候,没有做一些纸上的一些记录。但是基本上所有的一些问题在解决之后,都会保留进那个大仓的提交信息里面去

Q:那你印象比较大的一些问题有吗?

A: 其实就是工程师代码素养的问题。这是我认为最大的一个挑战。不是说每个人都会按照你的规范来,他们可能自己修改代码之后由于粗心或者其他一些原因,会导致其他人编译不过,其次不能做到立即发布到线上的代码,被夹带发布的情况,这些其实都是在大仓实践遇到的一些问题。然后偶尔会有这种事情发生,但是目前来说还没有造成过线上事故。

Q:但是我是很担心出现比较大的事故,比如你刚开始应该也是没有很多单测,没有自动化的用例吧?那个时候怎么保证代码质量呢?

A:对。就是在做大仓之前,我们单测是比较缺失的,每个人自己玩自己的,当进入大仓之后,这些管控非常严格,也在要求大家将单测慢慢补齐,我们花了大半年时间,所有的服务的单测从20%补充到80%,分支覆盖率从10%补充到60%,确实投入了很多人力心力去做这个事情

Q:刚才那个你讲的那个CR实践。比较表面的问题。那这种有没有利用一些工具或者什么的方法去保障?

A:是这样,就是我们的工具肯定是有的。而且有三套检测,但是工具不是万能的,涉及到一些代码设计上的问题就得需要我们自己去看了。工具能解决掉90%的问题,但是还会有10%的问题需要你去看,而这10%,往往是最重要的。

Q:我们旧代码进大仓有什么好的经验吗?难道都要全部重构掉吗?还是说旧的先放过掉,然后只是针对新增的代码做CR?

A:这个其实我们前段时间是在正在做的一个事情。我们从其他的同学那边接手了一批代码,这部分代码我们最近是在迁移到大仓过程中,我们安排实习生,应届生,或者刚入职的同学进行迁移。利用把代码规范化的一个过程让新手自己去熟悉代码,全部修复后再合入到大仓,而不是先合进去后面再修复。

如果是先合入后治理,极有可能就是一两年之后了。所以我们在准入这方面是非常严格的。

Q:CR这个问题。我再问一下,比如说我们开发一个可能比较大的一个功能,这个大的功能可能会写很多代码。你们规定是每次CR代码不能超过200行,但是即便就就200行,我整个框架都写不完。就像这种情况怎么办?

A:那这种情况就说明你们的拆分还不够细。当你拆分到一个原子化的时候,所有东西都是能够在一个函数内去解决的。我们腾讯员工一个开发一天的代码平均提交量是多少?是167行。所以200行刚好是一个同学一天的工作量。超过200行再提交,CR的人是很难关注你的代码逻辑的。

每个工作都是可以细拆的,你不要想着是一个很大的需求我一股脑的写完了,提交上去,会很有成就感,这种长时间编码会让人慢慢变得疲倦,反而容易出现质量问题。

本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
主干大仓也能toB,腾讯云小微不留质量后路的实战总结
就是在一个大循环之间,在用户反馈之前,我们内部先进行非常多的小迭代,这些小迭代通过以下行动项来保证用户得到是一个比以前更加稳定的产品
<<上一篇
下一篇>>