大厂的敏捷开发方法上

 大厂是如何开发软件项目的呢?其实大厂做项目也无特别之处,也就是工程中常见的“分而治之”策略:大项目拆成小项目,大服务拆成小服务,大团队拆成小团队。

    服务之间通过约定好的标准协议进行通信,架构上将大服务拆分隔离成微服务,大团队按照业务或者服务拆分成小组,按照流程规范保障协作。最终,各个小组负责的内容其实就不错了。

    所以归功于现在微服务、容器等新技术,可以将负责的业务主机拆分,让很多公司能真正敏捷起来。

    我们知道,团队要实施敏捷,不仅要小,组织还要扁平化,相对来说,美国互联网大企业做的很好,组织架构扁平,工程师地位很高。

    下面我们一起来学习一下大厂具体应用敏捷的方法。

和敏捷相关的主要流程规范

 

  • 一切工作任务围绕Ticket开展

    早些年的项目开发,都是围绕项目计划开展的,把甘特图打印贴到墙上,方便团队成员看项目进展到什么地步了,敏捷开发后,就变成了看板。

        所谓的看板,就是把白板分成几个栏,每一栏为一类,分别写着“To Do”、“In Process”、“Done”等,再把工作任务变成一个个五颜六色的即时贴,根据状态贴在不同的栏下面。

    大厂的敏捷开发方法上

    慢慢的物理看板变成了电子看板,通过各种项目管理软件来管理跟踪这些任务,即时贴也变成了Ticket(也叫Issue).逐渐的,所有的开发任务也就和Ticket挂钩了:

  • 汇报一个Bug,提交一个Ticket;
  • 提交一条需求,提交一个Ticket;
  • 要重构一下代码,提交一个Ticket;
  • 看板这种基于Ticket来管理跟踪任务的方式,看起来繁琐,其实是一种特别高效的方式。

  • 每一个任务的状态都可以被跟踪:什么时候开始做的,谁在做,昨晚没有
  • 整个团队的进度一目了然
  • Ticket和敏捷开发中的Backlog(任务清单)结合,通过Ticket可以收集管理整个项目的Backlog和当前Sprint(迭代)的Backlog.
  • 有了看板,大家每天上班来的第一件事就是打开看板,看看当前Sprint还有哪些Ticket没有完成,哪些已经完成,哪些还在进行中,非常直观。

        作为项目组成员,就无需在手头的任务完成后问项目经理接下来做什么了,从“To Do”一栏里挑选一个Ticket继续做就可以;对于项目经理,从“To Do”就能看到还有哪些Ticket没有做,“In Process”里还有哪些正在进行,如果发现哪一栏的Ticket好久没有动,比较多,就需要注意风险管控了。

    基于Git和CI的开发流程

        如果团队用瀑布模型来开发,最头疼的事情就是代码不稳定和部署太困难。

        早些年的源代码管理,大家都是在Master(主干)上进行开发,所以master分支的代码极其不稳定,一不小心就会被合入不稳定代码。所以一般在版本发布前都有一段代码分支锁定期,这段时间代码合入是严格受控的。

        测试环境的部署也是难题,服务一多,编译时的各种依赖和环境的配置就要格外注意,更新测试环境就是一个大工程,需要专门有人负责测试环境。

        对于“代码冻结”和“专人部署”方案,一点不敏捷,好在基于Git的开发流程和结合CI的自动测试部署很好了解决了这两大难题。

    Git本来只是源代码管理工具,但是其有强大的分支管理和灵活的权限控制,配合一定的开发流程,可以帮助我们很好的控制代码质量。

        我们现在假设master的代码是稳定的,那如何保证新加入的代码也稳定呢?答案就是代码审查(Code Review)和自动化测试。如果代码有严格的审查,并且所有自动化测试都能测试通过,可以认为代码质量是可靠的,当然前提是自动化测试代码要有一定的覆盖率。

        每次往master合入内容前,不是直接提交代码到master,而是基于当前稳定的master,克隆一个branch分支出来,基于branch去开发,开发完成后提交一个PR(Pull Request请求)。

    大厂的敏捷开发方法上

    PR提交后,我们可以清楚的看到代码哪里改动了,其他人可以针对每一行代码写评论提出修改意见,确认代码没问题了就可以通过代码审查。

        接下来剩下自动化测试问题,就该CI(持续集成)登场了。

        CI就类似一个机器人,每次你提交一个PR(严格来说是Commit)到源代码服务器,CI立刻就知道了,然后它创建一个纯净的运行环境,download我们提交的代码,下载安装所有的依赖库,然后运行我们的测试代码,运行完毕后把测试结果报告给我们,测试结果只管的反馈在PR上,绿色表示通过,红色表示不通过。

    大厂的敏捷开发方法上

    代码审查和自动测试问题都解决了后,就可以合并到master了,我们可以认为合并到master的代码是稳定的。

        大厂的敏捷开发方法上

    下面以一个开发任务为例,大致讲解一下应用敏捷开发方法的基本开发流程:

  • 把要开发的Ticket从“To Do”栏移动到“In Process”栏
  • 从主干master创建一个分支branch,基于分支去开发功能或修复Bug
  • 编写单元测试代码和集成测试代码,是否TDD不重要
  • 持续提交代码更新到分支,直到完成
  • 创建PR,邀请别人Review代码,根据Review结果,可能还需要更新几次
  • CI在每一次提交代码到代码库时都会自动运行,运行的目的如下:
  • 代码格式是不是符合规范
  • 运行单元测试代码
  • 运行集成测试
  • 最终CI把执行结果显示在PR上,绿色通过红色不通过
  • PR能合并到master需要满足两个条件:CI变绿+代码Review通过
  • PR合并后,CI自动构建Docket Image,讲Image部署到开发环境
  • 响应的Ticket从看板上的“In Process”栏移动到“Done”栏
  • 大厂的敏捷开发方法上

    正常来说,我们是需要严格遵守开发流程的,但偶尔有紧急任务,来不及写测试代码,我们针对这种情况,一定要再创建一条Ticket跟踪,确保后续补上测试代码,不要欠下技术债务。

    部署上线流程

        最早的时候,程序员自己管服务器,但是这过于随意,导致出现很多问题,于是出现了专门的运维团队,讲开发好的程序编译好,数据生成脚本写好,然后写成部署文档,交给运维去手动部署,过程繁琐慎重,遇到打补丁还要延迟。

        这些年随着随着容器化、微服务、DevOps技术和概念的兴起,部署变得高效,以前是运维人员按照文档部署,现在是DevOps写自动化部署工具,开发人员自己去部署生产环境,大厂的部署也都实现了自动化,但是流程受到控制:

  • 部署的不再是程序代码,而是Docker的Image,每次代码合并后CI会自动生成Image,测试也是基于Image
  • 部署生产环境之前,现在内部的测试环境充分测试
  • 部署生产环境前,需要审批确认,有Ticket跟踪
  • 部署是部分部署监测OK后再全量部署
  • 整个过程都有监控报警,出现问题及时回滚
  • 如果一切顺利,整个生产环境的服务部署过程通常只要几分钟就完成了,这以前简直是不敢想象的事情。

    每日站立会议

    敏捷开发中,每日站会是非常有名的,但凡实施敏捷开发的小组,每天上班第一件事情,就是一起开一个站会,沟通一下项目的基本情况和进展,开完会全身心去干活。

    是不是站着开会其实不重要,重点是要高效沟通反馈

    开会时间控制在半个小时内,半小时内不能完成的应该另外组织会议。

    在敏捷的Scrum中,有一个角色Scrum Master(敏捷教练,敏捷大师),主要任务就是保证各种敏捷流程的,他来主持会议,控制好会议节奏,主要有如下三个话题

  • 成员轮流发言
  • 每个人轮流介绍一下,昨天干了什么事情,今天计划做什么事情,工作上有无障碍无法推进。通过这样的形式,项目成员可以相互了解任务进展,有困难可以互相支援,及时发现问题和风险,当然每个人对自己提出的目标需要信守承诺,努力完成。

  • 检查最新的Ticket
  • 每天理会需要检查一下新增的Ticket,甄别一下优先级,然后决定是放到当前Sprint,还是放到Backlog任务清单,这个阶段要注意不能发散,不要针对Ticket的细节过多讨论,有需要讨论的收集放到“问题停车场”。

    大厂的敏捷开发方法上

  • 停车场问题
  • 总结

        在敏捷开发中的概念有Backlog、持续交付、每日站会等,这些概念最终要变成实践的话,必须通过一定的流程规范来保障这些概念的实施。

        这就是为什么公司要写自动化测试代码,用Jira、禅道项目管理软件来管理任务,每天开站立会议,代码审查,都是为了保障敏捷的正常实施。

        我们在实施敏捷开发的项目工作时可以多观察和敏捷相关的流程规范,再结合敏捷开发中的知识点,就能很好的帮助我们理解敏捷开发,理解流程规范背后的理论依据。

    此环节,大家可以针对之前来不及讨论的问题进行讨论,能在会议时间内解决的问题,立马解决,不能解决的私下讨论或者再组织会议。