商米科技成立于 2013 年,总部位于上海市杨浦区创智天地,是一家极具产品创新基因和互联网基因的公司。商米在短时间内迅速成长为一家近1000人的企业,产品研发人数占比一度超过70%。
做为一家初创企业,商米研发团队早期也经历过与当下大部分创业公司一样困境:协作基本靠吼、发布基本靠手的阶段。然而,业务的快速发展,团队规模不断的扩大,给商米带来了在「团队协作」和「工程效能」上的双重挑战。
一、蒸汽时代
为了能快速让团队进入步入正轨,商米研发团队早期采取和大多数企业类似的组织方式,以职能为单位的进行团队划分,分为前端、后端、Android端、测试、产品等职能团队,并采用传统瀑布研发模式组织团队协作。当时,我们称之为正规的研发模式。
每个团队由组长负责制,具体负责团队任务的分配、技术决策和人员培养,组员负责具体的研发任务。根据这样的职能协作的方式,商米建立了早期的研发流程:
产品经理进行原型图设计;
然后产品经理,分别找各个组长请求人员支持;
组长根据自己团队人员工作现状,将工作安排给相应的同学,接手产品开发任务,完成工作量评估、给出截止时间等;
最后再各自团队的同学,完成相应的工作之后,大家约好一个时间,集中联调一下,再交付给测试团队。
优势
劣势
资源不易空闲,需求排着队任何一个组员都能随时顶上
延续性差:分配任务时可能熟悉需求的成员在另一个需求研发中,其他成员不熟悉此业务
组长参与需求把关,设计方案得到保障
归属感差:团队成员不对业务成果负责,有任务就做思考业务不深入,潜能发挥不出来
组长分配任务,技术演进容易推动
研发过程难以保证:研发过程中没有监管,验收阶段常常出问题
相同专业成员坐在一块技术交流方便
组长被高度依赖:组长要参与评审、分配任务、解决难题、审核代码、推动演进技术、成为最大瓶颈
职能团队的组织方式,帮助商米走出了第一步。但是彼时,工程能力方面,却是一穷二白,别说CI/CD了,连部署工作都还是手工FTP上传文件,来进行服务器的发布。
没有专门的运维团队,服务器运维工作一直是后端团队承担,发布又是一个很重要的动作,出不的半点差错,只能让后端组组长进行发布,当业务不断发展,项目数量不断增多,负责发布的那个同学苦不堪言。
没有专业运维团队,没有现成的工具。只能硬着头皮去网上胡乱找一通,Jenkins太复杂,最后还不容易找到了一个简易的工具,解决FTP上传的问题,但最后的发布还是人工进行。
**小结:**通过建立职能团队,产品经理对接职能团队,寻找开发资源,以瀑布方式组织交付;工程能力方面,采用FTP纯手工上传方式进行发布,无专业运维团队。
团队的不断增长和快速发展的业务,又带来了新的挑战。团队间协作依赖,团队成员业务归属感差;同时,因为手工为主发布软件,通宵发布不是一件稀罕事。
无论是协作效率,还是工程能力上,这种老牛拉破车的状态,逼着商米团队进行转变。
二、电气时代
在寻找解决办法过程中,商米向Teambition学习,并引入Scrum研发模式,尝试将职能团队改造基于业务线的跨职能团队:
资源独享,组建独立业务交付团队,每个团队都包含产品、测试、后端、前端、Android端,跨职能;
采用Scrum工作模式,引入Scrum Master 和四次Scrum会议(计划会、每日站会、评审会议、回顾会议)
跨职能团队恰好能解决当时商米遇到的团队协作上的问题,但却无法兼顾职能团队的优势,于是增加技术委员会团队来支持业务交付团队:
遇到的问题
技术委员会的作用
敏捷组成员空闲
委员会分配公共任务或借调其他团队
设计质量难于保障
委员会参与评估避免成员单方面敲定实现设计
技术演进难以推动
委员会与SM协商排期增加重构或改进计划
技术交流减少
委员会定期进行技术分享,每周收集成员工作情况
通过敏捷化演进,在团队协作上"虚线"和"实线"发生了变化:
这种方式同时给SUNMI带来了另外一个改善,在成员评估上可以综合成果产出、工作状态以及技术能力多方面做出较全面的判断:
PO:评估团队成员的业务成果的贡献;
SM:评估团队成员配合过程中的积极性,响应速度;
委员会:评估团队成员的技术能力和技术水平。
如组员张三的转正评估:
为了更好的进行跨地域协同,数字化研发活动,在协作工具上,商米引入Teambition推出的敏捷模板,能够对Sprint进行规划,并且能够对迭代数据燃尽图进行分析。
在缺陷管理方面也从Mantis切换到Teambition的缺陷管理,和任务无缝关联。
同时,在文档协作上引入Thoughts工具,建立了完善的知识库体系;
研发协作模式的改变,给团队在协作效率和节奏上带来了真正的好处。团队再也不觉得自己是草台班子了,而是真正具备一家科技公司该有的样子。这是技术团队,在管理模式上的一次重大升级。
**小结:**采用以业务为导向的跨职能团队,有效解决职能间协作的依赖问题,同时增加团队的业务归属感;以技术委员会,从职能角度组织人员培养和技术决策;落地Scrum研发模式,让团队形成节奏感。
商米经过敏捷转型,解决了部分问题,支撑了团队规模和业务体量的进一步扩大,进入了新一轮增长期。除了支持企业内部的研发发布,同样商米也在构建自己的研发生态圈,按部就班的研发方式,显然难于应对当前业务的复杂性和不确定性,体量越来越大。
同时,随着产品服务化之后,服务的数量持续增加。业务复杂性,团队规模,还是技术的复杂性和耦合性,都给整个协作和发布效率带来了巨大的麻烦。
看似繁华的背后,却有着道不尽的心酸:
发布流程不规范
发布频次低,流程长,时间久
人工介入多,容易出错
漏测、搭车现像频繁
没有验证完,还不愿发的被发布了
每两个月就有由于流程原因导致的故障
信息同步不准确不及时
任务的工作状态与发布流程割裂
线上的事情线下做约定
发不发不清楚,发到哪不清楚
不知道具体应用什么时候有谁做过发布
各角色、各系统之间的信息分离
检查及测试手段匮乏
无检查无验证卡点,测试后置
检查验证手段有限,测试手工兜底
每次发布,验证周期时间很长
代码评审集中在少数人,有瓶颈
代码评审成为做样子
漏发、漏测
公地危机,环境问题
环境被长期占用,总是不够用
环境有脏东西,不清楚是什么
每次发布,对业务有影响,停机发布
如何破?成了商米技术管理者面前的一道难题。
三、高铁时代
加速:交付加速的基础发布方式的提升
一个偶然的机会,接触到阿里巴巴云智能的云效团队,我们决定联手解决商米当前面临的难题,经过分析,发现问题主要集中在以下几个方面:
返工:批量的集成,容易造成整个版本的失败,每次失败,所有的变更都跟着发不了。所谓,一粒老鼠屎,坏了一锅汤
阻塞:手工工序过多,形成等待、阻塞;依赖过多,等待其他的部署
落后的技术:手工测试,流水线手工串接及触发,信息同步靠口口相传,纯手工维护所有文档
债务:无测试自动化,无有效的代码扫描手段,无单元测试,应用间耦合高
分析完这些问题,在云效团队的帮助下,我们分别从整个流程和每道工序上进行了优化。
通过"行云/飞流"工具套件,商米解决了工程效能的问题:
第一步:自动化部署流水线,释放运维人力。一是对部署能力上,进行自动化改造,不再让发布成为瓶颈,团队想发就发,发失败了也有相应的自动化应急措施。另一方面,在整个流水线上,通过基于飞流提供的流水线模板,快速创建了自己的流水线,并同时进行了改造,保存为企业自定义的流水线模板,这样,当有团队需要用到流水线时,自动从模板上复用下来,减少了配置和推广的成本,默认从同一个模板上生成的流水线,在规范上是一致的。
第二步:建立质量保障机制,建立质量卡点,防止低级错误漏出;完善代码扫描、单元测试,从源头控制质量;同时,通过飞流的Jenkins插件,把我们之前基于Jenkins job的测试任务对接进来,完善掉测试屏障。
同时,灵活卡点设置,根据团队业务情况动态配置研发流程。
与此同时,我们直接采用行云提供内建的代码规约扫描和安全敏感信息扫描,从实际上的效果来看,直接在配置上打开就可以了,还不错。如果采用非主流的开发语言,可以把扫描做为流水线当中的一个阶段任务,对接进行来就可以了。
Code Review的能力同样采用了行云内置的功能,代码的浏览和主流的云上编辑器差不多,可以单行给comments,并且可以将code review设置为强制卡点。团队code review的实践很容易在这个工具下进行。
我们早期维护了一些自动化的测试用例,一直都是通过Jenkins Job进行运行的,采用飞流的流水线之后,通过飞流的Jenkins插件,也把之前的测试用例给跑起来了。
第三步:通过流水线的编排能力,为业务交付团队提供发布部署顺序上的编排,由业务交付团队自行控制发布的时间、顺序。团队不再依赖专职的运维同学帮助发布软件。运维团队也逐渐从发布工程师,慢慢往SRE的路上发展。而之前,都是需要开发工程师反复写好发布的说明,由运维去执行。
第四步:整个流程可视化,发布状态实时感知,日志完善方便研发排查问题;
我们听过很多的方法,接触过许许多多的实践,但画在PPT上的流程难于落地,写在书上的方法离我们太远。技术人在意的是实实在在解决问题,将流程和方法,内建在工具上,是这次转变的最大收益。
真正做到流程工具化、过程自动化、反馈数字化。工程能力的巨大的提升,同时进一步促进了协作方式的转化。
工程能力建设作用于协作方式的转变
由于开发和运维在工作流程上割裂的原因,在团队协作看板上,也是割裂的,彼此完全基于不同的单元在组织工作。
两周的迭代,第一周,需要主要集中在团队开发看板上,第二周,发布请求主要集中在运维发 布看板上 。
Scrum Master在开发团队的看板上刚组织完需求协作:
又得到运维看板上去协调发布请求,并且建立发布请求与需求之间的关系:
当发布工作完全由团队自行决定后,团队可以自行控制发布节奏,很自然地融合了开发看板及运维看板,形成完整的需求交付生命周期,基于需求组织交付协作。
引入飞流DevOps工具,工程师可以直接从需求/任务卡片上创建变更分支,自动就将代码变更与需求/任务卡片进行关联,代码变更的提交,同时自动地触发的流水线,流水线的状态也同样会显示到开发看板中,大大减少了信息同步过程花费的时间。
真正做到基于一个团队开发看板,就能可视化代码变更、发布流程所有信息,将隐性的工作显性化,进一步简化了信息同步,促进了协作。
每日站会,开发者基于teambition进行需求或任务指派
开发者基于需求/任务,自动创建变更分支
将需求的代码变更提交到变更分支,在行云上,采用内置的代码规约和安全扫描,完成代码检查,并发起代码评审
代码评审通过,自动触发发布流水线
中间所有的代码变更、发布流水线状态,全都自动同步到需求/任务卡片上,保证需求上汇集协同所需要的全部信息。同时钉钉机器人将发布过程中的任何问题,自动推送给开发者,完全精确反馈。
从2019年12月20号开始,截止到2020年2月21日,在短短三个月里SUNMI从零开始,做到了从「蒸汽时代」到「高铁时代」的蜕变,到现在:
使用Teambition进行任务协作共521名成员,Teambition近期活跃项目49个;
使用Codeup管理138个Git项目,3个月来共使用MR合并审核代码964次;
使用Flow管理120条发布流水线,3个月来共运行过3910次,成功上线771次,平均每天65次构建,12次生产发布。
发布窗口期从周二周四演进到随时可发,发布时间从数小时到一天半缩短到半小时以内;
交付速度从两周一次交付缩短到一天能够发布三次,交付三个功能点或修复BUG交付到用户手中;
商米引入"行云/飞流"工具套件再加上协作方式的改变,为整个商米软件研发效能带来了巨大的提升,真正意义上的进入了“高铁时代”。从过去每周两次的发布窗口期改善为随时可交付,部分团队甚至一天可以进行三次交付,大幅节省了运维发布时间,不再依赖人工操作和当面沟通,团队内部可以在一个TB看板内关注到需求交付的全过程。
小结:优化部署流水线,按工序持续完善质量保障,为持续交付建立工程能力基础;同时,工程能力的提升,也促进协作方式的改进。
三个阶段小结:
阶段
协作方式
工程能力
蒸汽时代
职能团队,传统瀑布方式
纯手工,借助FTP工具发布
电气时代
跨职能团队,Scrum方式
开源工具,手工,专职运维发布
高铁时代
全职能,精益开发,Teambition
阿里行云 & 飞流,自动化,开发自运维
从DevOps到SecDevOps
不光要快,还要安全。无论是真正的高铁,还是DevOps。对于中小企业来说,安全就是生命线,谁也不敢在资产安全问题上掉以轻心。
针对中小企业来说,要完整地构建安全编码的能力,缺少这样的实践,同时,也缺少比较好的规则引擎。我们采用行云内置的代码规约扫描把一般的编程中容易导致安全漏洞的代码给识别出来,同时,我们也通过一些敏感信息扫描,来识别是否有把安全相应的信息给明文化出来。
同时,针对工具平台本身的安全,同样采用行云和飞流提供的白名单设置,权限管理等,来提前做好安全的防控,做到事前预防;同时,在过程,工具平台,还可以对一些异常行为(如批量的代码转移或删除动作)进行监控,提前提出预警,做到事中监控;如果一旦发现有问题,我们也可以利用平台的日志功能,来做到事后追溯的目的。
整体上来说,这些安全的能力已经完全够用,如果不想用到这些能力,想用自己的话,也可以,disable掉,接入自己的就可以了。不过,我还是建议那些没有太多安全防控能力的企业,直接采用平台内置的功能,省得重复制造轮子。
写在后面
问题永远是创新发展的发动机。在商米走向DevOps的路上,正是这样一个个的问题,促使着我们去探索发现,也正是这样每一次的探索发现,在解决问题路上的那点小纠结、小成就、小雀喜,让我们在解决问题的路上走得更坚定,更有信心。
感谢在我们成长路上帮助过的人们,正是你们的毫无保留地帮助,才让我们走得越来越有信心。我们依旧在路上。
希望我们的故事,能够对你有一点点启发,那怕只是一点点,我们也会很开心。
参考
- 阿里云智能云研发团队:《跨越敏捷,企业DevOps解决方案》
作者介绍
文振熙,2015年加入SUNMI科技,一直从事云计算研发管理相应岗位,当前任职「SUNMI-云计算委员会主任」、「SUNMI-SBS业务线后端委员会组长」。曾推动SUNMI多次转型:Go语言推广、全面SOA服务化、K8S容器化落地、Wayne自助平台以及《行云/飞流》CI/CD落地等。
开源作品:
CSDN认证专家(http://w-blog.cn)
PhalApi PHP-API开源框架核心开发者
sunmi-OS/gocore & wenzhenxi/gorsa 开源项目作者
刘文沣,2017年加入SUNMI科技,从业务开发至前端研发管理,现任职「SUNMI-SBS业务线前端委员会组长」。先后承担多次技术攻坚及推动技术演进:ng1向react栈的迁移改造、基于webrtc的设备远控功能、 前端自动化构建及容器化部署、项目微应用化以及「行云/飞流」CI/CD落地等。