我们再回到业务层上来具体看一下如何提升研发效率。说到研发效率还真不仅仅就是如何写代码这么简单,读过《人月神话》一书的人都知道,要开发一个产品,并不是人越多越好,而是涉及人与人之间的信息传递成本,有时候人与人的沟通成本甚至大平写代明的成本,多外,当系统查复杂r以后,代仍应该写在哪里,也就品人数 去理解这个原有的系统也变得很困难,有个冷笑话,评信个业务需求, 先罗找各后真正写代码只需要1天时间。由此可见, 大部分时间并设有真正化在实现业务需求一个系统的产品经理花上2周评估时间,然后开发同学再用2周时间评估怎么实现,最上,这样的研发效率肯定是不合理的。
所以要考虑如何解决人性化,人与人沟通的问题,这是解决业务研发效率的关键所在。
1.沟通效率问题
有合作必然就有沟通,提升沟通效率最好的办法就是形成默契,要形成默契就要通过规范和约定等手段把大家圈在同个语言频道上。
需求阶段的沟通比较多,如统术语,需求结构化表达,统业务身份。
(1)统一术语。这在一个公司非常重要,比如在某些公司,“PM"这个词是指产品经理,而在另外些公司是指项目经理;还有诸如应用,系统,模块这些基本的称谓,如果大家理解不一样的话会很糟糕。
在公司中形成术语也有些技巧。比如给产品取一个好名字,名字既可成为术讲也可以是很好的传播符号,像滴滴的个服务框架叫DiSF ( didi service framework,滴师傅),这个名字有内容、有含义很容易被记住。在公司中与人沟通也是一样,如果很难一句话向别人说清楚某个产品或者项目,那么推广起来就会比较费劲,因此,把自己的产品,项目或任何需要向别人表达的事情术语化可以减少沟通的成个。
(2)结构化表达需求。互联网公同中都是需求驱动产品和技术的,提出需求的人大多都是运营和产品经理而非技术人员,这就不可避免地存在不同岗位人员的沟通理解问题。需求的结构化表达就是把需求用“ 系列的术语、图标、页面等可以更好理解和呈现的方式(一般产出就是PRD)在同一个语境中表达出来,让对方更好的理解。沟通需求的过程就是把不确定性确定下来的过程,需求越具体沟通越容易。把需求结构化,和把系统中需要经常改动的逻辑配置化要达到的效果是样的,最终产生的结果就是一个变更记录。
(3)统业务身份。业务身份是管理一个业务在各个业务城中定义的业务规则索引,是一串平台可识别的编码,该编码由构成业务的要素经过一定组合关系运算生成,在平台的运行城中,各个业务域的系统根据输人的参数条件,进行业务身份判断运算,最终根据识别出的业务身份结果,执行该业务在本系统定义的业务规则。要实现统一业 务身份必须要解决:
系统之间同一项业务的联通性问题,让系统自动呈现业务整体视图;
业务条件没有生命周期管理、系统长期维护困难的问题,要统一业条件识别;
业务上下线相互影响、回归工作量大和效率较低的问题。这就要对业务逻辑进行能力抽象,建立封闭性,从而隔离业务。要对业务身份进行统一管理,需要实现:
对业务身份标识的统一注册和管理,一般需要构建一个运营平台;。有业务规则的配置界面;规则的执行引擎。
所以统一业务身份需要人口的注册管理、规则的配置与变更,以及规则的运行域,缺一不可。
2.开发效率
如何高效地写代码是程序员永恒的话题。这涉及很多因素,如程序员对代码语言本身的掌握程度(比如JDK8中引人闭包代码可以使代码更简洁),写代码所用的IDE以及快捷键的使用程度,等等。笔者在这里先抛开这些问题,阐述下从开发到测试再到运维的整个效率问题。
开发,人员都不希望别人乱碰自己写的代码,对代码有绝对的控制权,所以一般都喜欢掌控(Owner)系统,即这个系统我说了算。在这种情况下,曾有一段时间我们把系统拆得很小,结果诞生了很多同质的系统,越来越多地在做重复的事情;此后又经历了系统合并的阶段。但是,系统合并也会带来新问题,即开放过程中冲突比较厉害,包括打包部署的效率都很低,在这种情况下会有两种解决方案:一是开发态和运行态分离;二是对系统进行分层和抽象建模。
所谓开发态和运行态分离,就是大家线下的开发都是独立进行的,包括打包和部署,接口的调用分开,走远程调用。但是在线上部署时,都是部署在同一个容器中,把远程调用变成本地调用。这种思路我们在“合并部署”一章中有介绍,本质上可以做到开发态和运行态的分离,同时兼顾开发效率和运行效率。
3.测试效率
整个软件生命周期涉及很多环节:需求、开发、测试、上线、运维…涉及很多协作。这些环节都会对效果有影响。其中,测试效率非常重要,因为测试花费的时间几乎和开发所花的时间是一样的。关于如何提升测试效率,我们总结了一些实践经验,分述如下。
(1)全链路Beta测试
继续保持Beta环境与线上环境的一致性,将核心链路上的应用,Beta环境HSF打通,减少90%由于环境问题导致的P1、P2故障。
打通之后,可以实现以下效果
测试环境可以做到召之即来,挥之即去;
在分批发布前,可以在极短的时间内有针对性地验证核心功能;也可以选择性地屏蔽 Cache的访问;数据轨迹可以实时透出。
4.运维效率
运维包括线上和线下两部分,运维效率会在两个环节表现得最明显,一个是线下的打包编译步骤、代码分发步骤;一个是线上的下线一重启一上线步骤、发布检查步骤和回滚步骤。下面我们分别看看在这些环节有哪些地方可以优化。
1)打包编译环节
优化流程。环境分配,可以预先分配好代码copy,要主动准备而不用每次编译代码时再做环境方面的准备工作;
预处理。监控代码版本修改,当代码被修改后,自动触发代码合并冲突检查做代码编译和打包操作,不要等到用户点击再触发;每个分支代码更新主动和主干做 Merge,发现有冲突要主动通知相应开发人员修改,不要等到打包部署时再临时修改;
代码编译优化。规则检查,业务依赖的包要做依赖规范化管理,通过工具识别依赖;减少应用依赖 SNAPSHOT版本Jar,可以节省 Maven编译时间; Maven打包优化,优化 Maven配置减少不必要的消耗;
增量编译。减少编译时间的办法之一就是只编译变化的部分;比较代码修改时间和编译的代码更新时间可以区分那些修改的类,并针对它们做增量编译,大大减少编译时间。
打包机器硬件升级。提升编译速度的另一个办法是升级机器硬件,使用更多的CPU或者更多的内存可以明显提升编译速度;多组机器 standby以处理并发修改情况,并始终保持应用处于可用状态,减少开发上厕所的次数。
(2)代码分发步骤
代码分发主要考虑两个问题,一个是代码的下载,最好是支持P2P下载,这样的下载效率最高(虽然大部分情况是HTTP下载较多,但真心不建议采用);二是如果代码包比较大且同时下载的机器比较多时,要考虑下载机器的网卡流量是否满足,这点必须特别留意。
(3)下线、重启、上线步骤
下线环节。下线被动等待15秒健康检查失败,能否主动通知LVS下线,而不是被动等待3次3秒的检查失败后再下线;
重启。初始化各种服务,去掉不必要的服务初始化,将一些服务改成慢加载,部分服务可以并行初始化。
(4)回滚
回滚等于重新发布,直接利用本机的老war包快速重启,不需要再走包分发步骤,要有手动回滚脚本。如果回滚时间长则减少回滚批次,采用发布一批机器就下线一批机器的方式:下线的机器保持 standby,老代码不提供服务,出现问题后再立即下线新发布的机器,将 standby的机器立即上线。这样可以快速达到回滚的目的,在30秒内就能完成回滚。