年前在部门内部做了一次分享,是关于工程效率的 。虽然在线人数不太多吧,不过确实是自己精心准备的。所分享的内容是一线作战积累下来的宝贵的经验。现在抽空总结以下,和有缘的同学一起交流下。

效率这个词相信大家都不陌生,每个企业每个人都在提倡降本增效。那么什么是效率?效率指单位时间内完成的工作量,当然这是效率的字面定义,效率其实与做工的快慢没有直接的关系。有些同学虽然做的很快,一个需求很快上线,但不注重产品的质量,往往需要后期花费数倍的时间去弥补隐含的问题。我理解的高效率应该是在指定的时间内持续做高质量的事。

工程效率可操作的内容很多,一线互联网公司往往有专门的团队在负责。我今天想介绍的是工程效率中的一小部分,即:一套基于实际的开发流程。

工程效率管理--高效的开发流程

高效的开发流程

先说下背景情况:作为流量的入口部门,我们团队承担着大量的业务支撑,一周有几十个case排队上线。每天都有版本上线,那么该如何平衡各个业务方之间的步调,保证上线没有问题,在实际工作中如何做到高效的? 这得益于一套完整的项目开发流程。

应用开发周期

工程效率管理--高效的开发流程

如上图,这个是个应用开发周期环,我们的所有需求都经过这几个步骤:

  1. 目标:企业的所有生产经营活动都是为了实现一定的商业目标,需求也不例外,产品提出的所有需求都是为了实现一定的目标。
  2. 由相关的产品根据目标细化成具体的需求,提给项目中相关干系人,包括设计,前端,后端,平台等部门。
  3. 我们作为服务端开发团队进入开发,在适当的时间点进入开发,通过开发和联调完成初始的开发工作。
  4. 完成后反馈给业务方产品进行测试,如果没有问题,会要求业务方进行一定的方式进行反馈,此过程我们一般要求邮件进行反馈。
  5. 然后我们的需求代码进入代码merge,在规定的时间点由专人进行合并,并创建代码tag,然后通过CI集成发布部署到仿真环境上。
  6. QA同学根据邮件列表中上线的信息内容进行测试,主要进行常规内容测试。如有必要,业务方此时也需要参与测试,确认没有问题。
  7. QA反馈没有问题后,在规定的时间即由专业的人员安排上线。
  8. 如果达到目标期望,则此次需求开发圆满完成,如果线上监控异常(错误率, app crash,服务器报警等),则需要进行回滚。

之前我们人少,对接的产品人员需求也没有这么多,后来随着业务的快速发展,我们的业务也变得复杂,于是一些不正规的操作影响点也开始放大。
如:口头沟通,规范不统一,QQ,微信,邮件等都有,描述不清楚。之后不可描述,追溯困难,造成了维护成本高,需求质量把控基准低,上线翻车事故频发等。

工程效率管理--高效的开发流程

此时,我们需要对现有的流程做些规范和改进。
下面主要从需求,开发,测试等进行说明:

需求管理

根据上面的生命周期环,需求是第一步,我们首先解决需求方式不统一的问题。根据自身业务的特点,我总结如下:
需求的几个要素包括。

  1. 对接业务方和项目。
  2. 需求的进度和阶段。
  3. 谁在跟进,即开发者是谁。

另外还有几个不太重要的因素:

  1. 完成时间---其实很重要,不过根据实际情况,没有在我们需求管理系统中反馈出来,开发的链路长和项目的不确定因素太多了,一般在邮件中反馈出来即可。
  2. 其他内容

综合的考虑了我们的业务场景,结合兄弟团队的情况,我们决定使用gitlab issue进行需求管理。
这里有个原则,你的技术选择不要曲高和寡,一定要结合当前的业务场景和使用者进入的困难程度考虑。

工程效率管理--高效的开发流程

需求管理和研发流程两条线

虽然我们跟其他团队一样,使用了gitlab issue进行了需求管理,但是我们这里不仅仅用到了手工拖动转变issue标签的功能。更多的是通过web hook的方式,跟其他内容联动。这个是在gitlab issue上进行的二次开发的功能。具体体现在以下几点:

  1. 当PM创建需求issue后,此时触发web hook脚本,会向admin消息服务发送确认请求,如果有问题,内容不符合规范,则进行不合规的邮件提示。
  2. PM此时需要和我们的开发人员进行线下沟通,进行需求的确认,当然这也可能发生在1之前。
  3. rd进行创建本地分支进行开发,此时我们用了git hooks进行人性化的提示,告诉rd应该手动去更改issue的状态。当然设计的时候是设计开发中和联调测试两种状态,不过实际应用中,并未进行严格区分。
  4. 当需求代码在联调环境测试没有问题,可以上线的时候,此时开发者需要严格的按照规范进行提出代码的merge request。
    此时一般会要求在指定处追加提案。此代码merge发起后,会调用admin消息服务,触发一个任务,主要进行对merge request的检测和issue的内容check等。如果不符合标准,则添加醒目的标签提示。
  5. 在所有的merge都合并完成后,需要创建第二天的上线tag,然后触发gitllabCI进行自动化部署到仿真机器上。此时,创建tag和部署成功都会回调admin消息的接口,进行创建tag和仿真部署成功的邮件提示,然后QA基于邮件的内容进行测试。
  6. 上线,当上线成功后,运维的上线脚本也会回调admin消息平台的接口,进行上线成功的消息发送。此时一轮上线完成。
    工程效率管理--高效的开发流程

gitlabCI

关于gitlab CI的概念,我这里不想说的太多,我想主要是以下的流程吧:
前置条件:
gitlab支持gitlab CI + 运行CI脚本的runner机器(Server) + 项目的CI配置文件.gitlab-ci.yml
当配置了一些触发条件后,所有命中的特征动作均能引起任务的执行。
如:代码提交,创建tag等等。

工程效率管理--高效的开发流程

git开发模式

关于开发模式,得根据业务场景而定。如果项目比较小,而人员比较少,可以在项目里直接创建分支进行开发。但是如果项目复杂,维护人员比较多,通常采用fork模式,fork模式也是github上维护开源项目公用的方式。具体过程如下:

  1. 在gitlab上从公共空间项目fork到自己的空间下。
  2. 通过git clone到本地。
  3. 在本地自己的项目里创建分支进行开发。
  4. 如果没有问题,push代码到自己远端的项目里。
  5. 需要上线的时候,创建一个从远端自己空间的项目分支到公共空间下的项目的merge request。
  6. 等待专业人员review并合并。
    工程效率管理--高效的开发流程

维护分支

关于公共空间的维护分支,我们同时维护三个分支master, release branch--常规上线分支, emergency branch--紧急上线分支。

  1. 初始阶段,三个分支的代码进行统一。
  2. 开始开发的时候,每个rd从master进行fork clone进行开发。
  3. 当开发完成后,在自己的空间发起merge request到release分支。
  4. 然后基于release分支进行创建tag,并走常规测试流程。
  5. 如果QA常规测试没有问题,则把4中的tag推送到线上,此时如果线上测试没有问题,把release代码同步到master和 emergency上面。然后进行下一周期的上线。
  6. 当遇到紧急上线的情况,我们一般基于master进行同步,取得线上最新版的代码之后,将紧急上线的代码合并到emergency里面,然后创建tag上线。当紧急上线都ok后,我们把代码同步到master和release上,
    此时如果release上有准备上但是还没上的代码。则重新创建tag,继续进行常规上线的测试。
    工程效率管理--高效的开发流程

常规上线和紧急上线

根据时间的紧迫程度,我们这边分成了常规上线和紧急上线两种类型的流程。所谓的紧急上线,其实就是牺牲掉了质量(缺少仿真测试),优先选择了时间,大致流程如下:

  1. 开发人员接到需求后在本地开发及自测。
  2. 感觉没有问题,上传代码到git,然后创建联调环境,代码引用前面上传的代码分支。
  3. 如果业务方测试没有问题,开发人员在接到明确请求的情况下,进行提出代码merge request。
  4. 在每天固定的时间点--上次上线完成之后,我们进行统一合并代码,进行第二天的准备工作,此时推送到仿真测试环境上,进行QA测试。此时如有必要,也要求业务方进行仿真测试--QA测不到一些特定场景的内容。
  5. 当没有问题后,进入后续的上线流程。
    工程效率管理--高效的开发流程

上线的流程

一套标准的上线动作包括以下过程,前置条件:准备上线的内容,即上线tag,QA仿真测试报告。当一切都ok之后,在特定的时间(我们一般定在上午11点左右)由值班人员负责上线。上线采用灰度到全量的上线方式,先对内部的一组服务进行上线,然后进行观察监控指标(IO,磁盘,内存,CPU 错误率等),如果有异常迅速回滚,如果没有问题,向admin消息中心发送一条消息,同时相关干系人,上线完成,上线的内容和上线的结果等。
工程效率管理--高效的开发流程

上线流程图

因为我们的开发语言使用了php,跟java的区别是不需要整体编译,所以我们依然采用了增量推送代码的方式进行上线,在日常的开发中,代码也具有局部少量修改的特征,这种方式代价也比较小,非常合适。同时,我们在推送代码的同时,也会进行创建新的镜像。这个镜像在扩容,或有docker服务重启的时候可以用到。即:存量正在运行的机器使用旧的镜像+新的代码,新生的容器使用新的镜像启动。两者保持最终一致性。

工程效率管理--高效的开发流程

当然还有另外一种上线方式,如其他某团队,就使用完全基于docker的方式上线。过程如下:
当需要上线的时候,由Jenkins进行创建镜像,并推送到docker仓库,然后拉取镜像推到线上机器,重新启动容器的服务,达到上线效果。
这种方式:是以docker镜像的版本进行上线管理,如果需要回滚,则使用上一个稳定版本的docker镜像即可。

工程效率管理--高效的开发流程

镜像和环境隔离

工程效率管理--高效的开发流程

总体来说,我们的环境分成这四种环境:本地环境,测试联调环境,仿真环境,生产环境。

每种环境使用不同的docker镜像。其中本地环境和测试环境使用测试docker镜像,而仿真环境,为了排除环境的差异,进行最真实的测试,我们和生产环境一样,用生产环境docker镜像生成容器。同时底层的基础运维环境,我们也进行了统一管理和隔离。

以上,是我今天总结的全部内容,欢迎一起交流,共同进步~