背景
对于追求效率的程序员来说,影响工作效率的事情,是深恶痛绝的,当大家拿到任务的时候,其实对于工作量的评估,心中大致都是有一个数的,然而,为什么我们交付的时候,大部分情况下会比估算的时间长呢,有时候还会长达几倍之多?
我总结的几个会影响交付进度的关键问题
- 工位周边的环境干扰,例如把销售人员和研发人员放一起;
- 电脑的软件环境或硬件环境出现问题,例如
go
的版本和其他人的不一样,编译他人的代码时会报错; - 需求变更或理解不到位;
- 庞大的技术桟;不同团队不同的开发语言,甚至有的是同一个团队不同的开发语言和框架,🤮吐血。。;
- 架构上有重大设计缺陷,例如有些功能无法通过某种方式实现,后期又得修改,此路不通;
- 前几周都在写Bug,后几周在改Bug🐞,你看我工作多饱满🤓;
- 在测试时或发布时阻碍较大,例如Bug多,研发环境和生产环境环境不一致。
这里不谈技能Level问题,我们统一认为水平为中级程序员即可
如何解决?
本文主要是解决研发顺畅度问题的,从开发
-> 测试
->发布
的效率问题,当然,既然上面提出了几个影响效率的因素,那我就先说一下这几个问题我们是怎么解决的,虽然不是最优方案,但一定是适合我们自己的团队的,我们团队人较少,情况大致如下:
- 后端4人
- 前端3人(ios+android+web 采用ReactNative)
- 测试2人
但是产品内容较多,比如我们需要和第三方存管系统对接,第三方资产系统对接,需要提供管理员系统,手机APP,官网,以及其他周边的服务系统,如果不好好解决效率问题,仅仅凭借这些人员数量,是远远不够的,因为这里仅仅是包含了开发的任务,后续还有上线和解决线上问题的任务。
我来简单说一下我们是怎么解决这些问题的吧,希望大家能够给予建议,同时也很高兴能帮助到大家。
工位周边的环境干扰
我们是小公司,这个问题。。。。解决不了,大家都在一个特大开间里, 只能带耳塞和耳机了。。。不过我们的客服大部分是在微信上服务,以及出去跑业务的,因此干扰度不是特别大;
电脑的软件环境或硬件环境出现问题
我强制给大家配备Macbook Pro Retina
, 强制大家使用如下工具:
- iTerm2
- brew
- autojump
- Sublime Text
- oh-my-zsh
同时,我要求编译环境的库版本必须是某个特定版本,比如 go
必须使用 1.9.4
, 这些都是硬性要求,其他的大家是可以自由发挥。
大家可能会认为配备Macbook Pro Retina
笔记本的成本太高,但是我想说的是,这真的是一个提高研发效率的途径:
- 大家使用相同的操作系统;
- 命令行
unix-like
,linux上能用的命令,大部分都移植在mac上了,不需要搞什么cygwin
了,那玩意搞得真心难受, 最后效果也不是很好; - 流氓软件目前还没那么多,windows上动不动就是全家桶。。。;
- 比linux的ui系统好用;
- xcode只能在mac上用啊😄;
- 如果和同事共享文件,AirDrop就搞定,方便,而且也不用上传到某些聊天服务器上做中转了,心里踏实。
- 协作时,随便拿一台笔记本都像是在操作自己的笔记本一样,嗯,这个电影是?🎬
总之,好处多多,一定要说服你们的老板啊😏。
需求变更或理解不到位
一定要要求程序员做需求反讲,先是产品经理讲需求,然后是技术消化,最后研发给产品经理反讲,确保双方理解一致,对于频繁改需求的问题,这个没有太好的解决办法,因为有时候需求就是变了(这里不是说按钮要放到别的位置,颜色要换成什么,主要的是指功能性的需求)
庞大的技术桟
我们的要求就是后端只能用go
, APP开发iOS使用ReactNative
,打包自动化用gulp
, Web使用React
, Android就使用原生开发,主要技术桟列表如下:
- Go
- ReactNative
- React
- Gulp
- Android Java
- Docker
- Git
这么罗列下来,其实已经很多了,我们应该尽可能减缓技术桟列表的增长,要做好技术选型的把控工作,不要随意使用某个语言,某个框架。
架构上有重大设计缺陷
架构本身是随着环境的变化而发生变化的,需求
、体量
、痛点
是推动架构变化的主要原因,我之前做的是广告行业的技术架构,当时的痛点有如下几点(有些记不清了):
- 服务器多,当时Docker尚未兴起(我离职前不久还是很初级的版本,14年初,但Docker也是在那个时候快速崛起的);
- 我们后端使用Erlang开发,招不到人也是痛点;
- 由于没有Docker,部署是个大问题,从
研发环境
->测试环境
->生产环境
都有差异,因为这些差异,找问题需要找很久,有新服务器加入那更是痛上加痛了,上百台的服务器啊。。。。; - 因为是个大公司,所以一直在沿用
SVN
,后来给大家做了GIT
的培训,搭建了GitLab
, 使用了GitFlow
- 当时没有使用
CI
, 你就说痛不痛?其实大公司要使用某个工具,某个架构,某个流程,做大批量的更换是挺难的,所以很容易就这么痛下去,都2018年
了,我一个同事入职某60
,这些给研发人员使用的基础设施还很原始呢,我同事的原话:完全没法和我们现在的开发环境相提并论。
再说说我们P2P行业的痛点:
我们不跑路,我们是一家很正规的P2P公司,是金融办审查过的
P2P的业务特点如下
- 需要和第三方资产对接;
- 需要和银行、支付渠道对接;
- 需要和金融办要求的监管系统对接,比如合同、标的信息等等,都是要传过去的;
- 需要给客服提供客服平台;
- 需要给管理员提供管理平台;
- 有APP、PC这些自然是不用说了;
- 活动推广的体系你得有吧?;
- 用户活跃度追踪的体系你得有吧?
- 安全体系你得做吧?
- 最主要的特点是:不能错!!每天的交易都要和银行、资金通道对账,每天清算。
对了,大家如果忘记了我们有多少个人,可以往上面再翻一下,另外,这仅仅是我们的一条产品线,我们之前希望把控更多的资产,自己也尝试开始做资产管理,嗯,做了一个类似钻石抵押的借款平台,反正产品线多。。。
除了业务上有痛点,公司体量小,本身也会有一个致命痛点
招聘难:好的人才可遇不可求,我们面试到的程序员也大多是初级或中级的,高级的不多见。由于我们使用的是go
语言作为后端语言,ReactNative
作为前端APP开发框架,能找到合适的就是微乎其微了。大家别看这些概念都已经很火了,但在我们小公司里,几乎是招聘不到有这些实战经验的程序员的,大部分是只有一点开发基础的,只会一门语言,甚至没做过项目的,怎么办?培训+实战,没有别的出路。
基于这些问题,我们就有了一个架构设计的思路:
- 无论对外的服务还是对内的服务,统一使用API调用,这样我们可以用
postman
进行测试,或写自动测试工具进行请求; - 能快速搭建,要像乐高组件一样;
- 要像市面上兼容乐高组件的盗版乐高一样,我们一部分用正版乐高,一部分用盗版乐高也无问题,其实这一点很重要,我们是希望,在将来有时间、有精力了,能快速换掉质量不好的组件,因为一开始为了赶进度,质量把控可能就没那么严格了;
- 根据上一点的描述,我们可以进行服务降级,比如压力大的时候,将有复杂逻辑的组件替换成简单逻辑的组件
- 方便本地调试,也方便自动化部署运维;
- 压力大了可以做横向扩展,即无状态;
- 由于某个功能组件未实现,我们先放个Mock组件进去做测试,或做初期联调。
为了增加把控度,我们自己造了轮子,此框架适用于我们的应用场景,同时也是开源的,所以,非常欢迎大家使用,并给出建议:
前几周都在写Bug,后几周都在改Bug
Code Review
这项任务是必须要执行的,但仍然解决不了初级程序员,尤其是入门级程序员犯这个错误,第一是要提升这位程序员的技术水平,在每日例会上要碎碎念,多跟他讲讲设计、讲讲哪些东西合理、哪些东西不合理,经常讲讲行为规范,比如:
- 我们不要在
for
循环里一条条去执行sql
来查询结果,而是应该在for
循环前先一次性查回来再处理; - 涉密的内容不要提交到代码库;
- …...
真的很碎,但这是规范,也是文化的传承,小公司可以这么做,因为人少好叨叨,大公司则需要有严格的行为准则和制度,但也应该拆团队,培养主管对规则和文化的重视。
撸代码前做技术设计
做完需求反讲后,产品经理和研发人员都对需求有了一定的理解,接下来最好做一下技术实现上的设计,先做好磨刀的工作,再做砍柴的事。尤其是对于初级程序员,应该先听听他们的设计思路,应该给予及时的帮助和纠正,总比在最后让他们改BUG
强。
一定要做好BUG数量的控制,否则技术债务会像滚雪球一样越来越大,本来我们可以好好做研发的,却要去解决焦头烂额的线上问题,这是不能容忍的。
在测试时或发布时阻碍较大
大致会有如下的阻碍:
- 致命性的BUG多,解决同上一个问题
- 上线过程中一堆环境问题
- 上线后一堆问题,和测试环境、开发环境表现不一致
我们是这么做的
MOCK
尽早稳定好API
接口的定义,测试人员开始写MOCK
(只需要写个javascript
脚本即可,对请求内容进行判断,然后返回特定内容),这样就可以了,为什么要这么做?
- 后端开发
API
的实际逻辑实现会比较慢,前端需要使用MOCK
来完成对接,快速实现各个页面的逻辑联通; - 方便前端人员做前后端的集成测试,如果大家都按标准走,后续对接只需要更换服务器地址的配置即可完成无缝的切换工作;
- 测试人员在写
MOCK
脚本的时候,会把业务场景都过一遍,增加了测试用例的品质; - 嗯。你还可以拿着
MOCK
给客户演示😂
容器化、自动化
- 一定要使用Docker,包括编译代码的编译环境。比如
gulp
编译网站的时候,研发人员自己的机器能编译通过,放到别人的机器上编译就不行,因为安装的环境,类库版本有差异。如果放到指定的docker里去编译,则不会出现这个问题; - 测试人员是对部署后的Docker容器进行测试,测试通过后,则是部署被测通过的镜像到线上,确保环境是一致的(只是配置文件获取的数据源不同,出现异常时调整配置即可);
- 无论是哪个端,发布到测试环境和生产环境的程序,编译、自动测试和部署的任务均在CI服务器上进行,而不是开发人员自己的机器,除了上面提到的环境问题,还有就是:放到
CI
上做,就需要写好CI
脚本,一切都是按照预定的计划执行。
所以,研发人员的研发环境,是一种习惯、文化,更是一整套生态,从物理上的工作环境到电脑里的系统环境,从功能到架构,从研发到上线,每个环节都可能出现效率上的杀手。
后续
我主要会为大家讲解,如何搭建一个完整的从 开发
到上线
的环境,并且为大家讲解几个CI
案例, 同时实战gitlab-ci.yml
的写法,让每个团队享受CI
带来的便捷和乐趣。
我们用的是阿里云(小公司嘛,哪有钱搞机房),因此,后续的部署讲解均是基于阿里云的,大家也可以按照自己的需求,开发出部署其他云平台的模块,go-flow是插件化的。
涵盖的内容大致如下(后续根据实际情况做调整):
- 使用 go-flow 搭建一整套研发环境
- 使用
gitlab-ci
编译一个APK
- 使用
gitlab-ci
编译一个todo
程序的示例(go
),从代码提交
到发布
的整套流程 - 使用
go-spirit
快速发布mock
服务 -
PKI
(Public Key Infrastructure) 证书使用
一句话:不玩虚的,实战!实战!
详解前的Demo
先给大家放几张我们现在正在使用的系统的图片,全当时给干涩的文字配个图了。。。
使用go-flow
搭建下面这些环境的执行截图,嗯,我给大家带来的是全家桶,当然这些是基础环境,每个公司都会有自己的环境需要搭建,大家可以为 go-flow
贡献插件哦😬
大家不用尝试访问图中的地址啦,因为我迅速的使用 go-flow 释放了这些资源😀
我们研发所有的服务都做了客户端证书的双向认证,以防止外人的访问(PKI)访问服务时,会弹出如下提示:
没有客户端证书的人是无法访问的。
Gitlab
每次提交代码,都能触发自动编译和测试
部分任务可以指定为手动触发,比如部署,因为不是每次提交代码都需要部署
有编译的详细过程
不同的Runner用于跑不同的项目,比如编译苹果应用的runner就需要跑在mac上,我们公司有一台专门编译iOS应用的MacMini
LDAP
研发人员登录公司内部系统,都是使用的LDAP,用户可以自己登录修改密码。
Graylog
日志系统,我就喜欢graylog,好用, 结合好 logrus_mate 就可以往不同的系统打日志了。
Redmine
简单易用。
能看到最后,说明您很认真,欢迎加入我的QQ群进行更深入的交流:780798965