↑ ???? 万字长文不想看,那就听一听叭 ↑
互联网大公司价值上亿的项目背后,团队成员是怎么高效协作开发的?
和我自己开发辣条项目时有什么区别?
看完本文,保证让你大开眼界!
鱼皮在学校的时候,做过很多项目,但大部分都是练手的 Demo。基本都是单兵作战,毫无章法。
大二暑假,我第一次进入企业实习,要和同事合作开发一个大项目,对于企业中的条条框框和同事写的烂代码非常不适应,整天大呼同事不讲码德!
大三来到字节跳动实习,还是和同事一起开发一个新项目,那会儿仍然不适应团队开发,最烦的事就是每次写完代码,都要让同事检查几遍,确认没问题后还要在他的监护下才能发布上线。
后来走出校园,来到腾讯,接触到了更大的团队、更大的项目,但起初我还不能很好的适应团队开发,依旧保持个人开发时的野性,导致效率非常低。
经过在鹅厂一年多的摸爬滚打,如今的我,终于能够熟练运用企业的各种资源来提升自己和团队的研发效率了!
我总结了 30 个提升团队研发效能的锦囊,完整覆盖项目的各研发流程,分享给大家~
项目研发流程想要提升团队开发效率,在投入项目开发前,必须确认项目的技术选型。比如项目选用哪种编程语言、选用哪个开发框架、选用哪些依赖库、选用哪个测试框架、选用哪种数据库、选用哪些中间件等等。
技术选型是一门大学问,通常不是由一位技术大牛或架构师一锤定音的,而是要大家开会讨论,结合具体的业务场景进行分析,并且对技术进行充分的研究,最后共同确认一个较为合适的选型方案。
技术选型的考量要素非常多,比如:
团队成员对技术的熟悉程度。团队成员对技术越熟悉,培训成本越小,开发效率越高。在一个都是 Java 工程师的团队提出使用 C++ 简直不讲码德!
团队对技术的掌控度。团队内至少要有一个人非常了解该技术,懂得最佳实践,能够指导团队正确运用技术,并解决疑难问题。
技术的主流程度和生态。技术越主流,文档、实践和解决方案就越多,而使用冷门技术可能出现无法解决的问题,整段垮掉!
技术和业务的贴合程度。技术是为业务服务的,因此必须结合具体的业务场景去选用技术。比如在只有几个用户使用的小网站中运用微服务框架是一个愚蠢的选择。
工欲善其事,必先利其器。
在开发前,选择一款优秀的开发工具,并且学习如何高效地使用它吧!很多开发工具都自带了代码检查、代码格式化等功能,还有很多快捷键,这将大大提升我们的开发效率和开发体验。
目前比较主流的开发工具有 JetBrains 全家桶
、Vscode
、Sublime
等等,不必沉迷于某一款开发工具无法自拔,可以针对项目的类别和体积进行选择。
除了本地的开发工具外,还可以使用云端的开发工具,比如 Cloud Studio
,无需下载任何软件,直接在浏览器中进行开发和调试、实时浏览。对于小型项目的开发也许是一个不错的选择。
在开发前,为团队或项目制定一套代码规范太有必要了。
好的代码规范能够帮助团队成员阅读理解他人的代码,提升协作开发效率和团队氛围。
试想,如果你习惯代码缩进两格,而其他同学都缩进四格,会不会感到很懊恼?
在开发一个新项目前,通常由架构师或熟悉技术框架的同学来搭建项目的基本结构、编写 Demo,其他同学只需要在此基础上遵循规范进行开发(复制粘贴)就好。
如今,项目结构越来越复杂,我们不可能手动创建一个又一个文件。
懒人推动世界,很多框架自带了脚手架,能够让我们通过输入一两行命令,快速生成项目的基本结构、默认配置文件、甚至是可直接运行的 Demo,避免了不必要的重复工作,大大提升开发效率!
比如前端框架 Vue
的脚手架 Vue Cli
和前端框架 React
的脚手架 Create React App
。
低代码是指少写代码或不写代码。通过对应用场景的极致抽象和模板化,将写代码的工作交给机器来自动生成。
就像现在网上很多 App 和网站制作平台,只需要在界面上选择元素、点点拖拖,就能够自动创建出应用,根本不需要写任何代码,哪怕是不会编程的人也能轻松使用。
低代码构建在企业中非常流行,是提升团队开发效率的神器,几乎每个大公司都有自己的低代码构建平台。业界比较知名的低代码平台有 Google 的 App Maker
和微软的 Power Apps
等。
在开发中,我们经常需要下载大量的依赖包,还要将开发好的依赖包进行上传。
但是,通常软件依赖源都是国外的服务器,比如 Maven
和 npm
源,从国内下载依赖的速度非常慢。虽然下载慢的问题可以通过配置国内镜像源得到一定程度的解决,但是无法直接在公有软件源上传私有包。
因此,通常企业都会在内网搭建私有软件源,即内部依赖仓库,便于内部依赖管理,大大提升拉取效率。
目前最常用的内部依赖仓库是 Nexus
。
很多年前,在我还有一双清澈的双眼的时候,我在本地开发网站都是改一行代码,然后切换到浏览器里刷新看效果,然后再改代码,再刷新,如此往复,非常难受。尤其是开发后台应用时,哪怕在代码中改了一个字母,都要去重启项目!
现在想想,效率实在是太低了。
如今,本地开发热更新是程序员开发提效必备的神器,启动一个开发服务器,让它自动监听代码文件。当代码更新时,运行中的项目也会自动更新,从而省去了无止尽的刷新和重启。
在前端,比较知名的热更新工具有基于 HMR 技术(模块热替换 hot module replacement)的 Webpack Dev Server
;在 Java 后端有 热部署插件 JRebel
。
Serverless 是最近几年逐渐流行的概念,翻译过来就是 “无服务器”。
以前,我们要搭建网站的后台,首先要买服务器,然后将一个大而全的项目包部署到服务器上,整体对外提供服务,所有的系统资源和进程都需要由我们自己来管理。
单体架构随着云计算时代虚拟化、容器、微服务等技术的发展,人们将大项目的通用部分抽象成一个个细小的服务,每个服务只提供一个或几个功能,独立部署在比服务器更轻量且无状态的容器中,共同对外提供服务,组成一个完整的系统。
Serverless 架构而 Serverless 不是指完全不需要服务器,而是让开发者感受不到服务器的存在。
什么意思呢?其实就是把对服务器的需求外包给厂商,我们只管写代码,让他们负责部署和运维。我们花钱,他们办事!
目前国内有很多 Serverless 服务提供商,如阿里云、腾讯云、LeanCloud 等,使用这些 Serverless 服务后,我们无需再关心服务器的运行,只需要专心写业务逻辑就可以了,能够大大提升开发和维护效率,省时省心。
很多年前,我们的代码几乎都存在自己的电脑里,通过 U 盘或者网络传输代码文件来实现合作开发。
而如今,代码托管平台已经成为团队合作开发的灵魂。
相信很多小伙伴都接触过 GitHub
,世界上最大的代码开源托管平台。每个人都可以把自己的代码发布到 GitHub
上,作为一个代码仓库,随时随地远程管理。还可以搜索和浏览其他人发布的代码仓库,以此实现高效地合作开发,促进项目的完善。
为了保证代码的安全保密性,一般在公司或团队内部都会自己搭建一个代码托管平台,比较知名的有 GitLab
,可以针对不同的项目为成员分配权限,更好地管理团队的代码。
在代码提交之前,首先应该在本地进行代码检查,及时发现一些低级的语法错误,防止被团队的其他同学嘲笑。
大多数集成开发工具自带了代码检查功能,边敲代码边检查,非常爽。
此外,我们还可以配置 Git Hooks
,在代码提交前自动执行代码检查,npm
项目可以通过 Husky
插件实现,还能配合 ESLint
实现代码自动修复。
团队越大,规范就越重要。
只有代码编写规范还不够,还要在团队内制定一套代码提交规范,通常是约定式提交规范,即让成员在提交代码时填写指定格式的 Commit Message
,比如下面的格式:
<提交类型>[可选的作用域]: <描述>
[可选的正文]
[可选的脚注]
指定代码提交规范不仅能够帮助成员快速理解每次提交的改动点,提升代码审查效率;更大的作用是让一些自动化工具理解提交信息以进行一些有意义的工作,比如生成 Change Log
(代码改变日志)。
可以参考一些大公司的代码提交规范,并通过 commitlint
和 commitizen
等插件实现自动修复不规范代码。
在团队开发中,写代码可不能像自己练习编程时一样肆无忌惮。
在合作开发时,可以为每位开发者分配一个分支,在自己的分支编写和提交代码,也可以按照需求来建立分支。确认开发测试完成后,发起一个 MR(Merge Request 合并请求),将小分支的代码合并到公共的主线分支即可。
分支合并主线分支的代码通常是能够直接发布上线、稳定运行的。因此,为了保证项目代码的质量,每次合并代码到主线分支前,必须要进行代码审查(CR,即 Code Review),就是让同事或上级阅读和审批你的代码,觉得没有问题后,才能够执行代码合并。
通常,代码变更越大、项目越重要,代码审查所需人数越多,越能够发现一些个人无法发现的风险和问题。因此,代码审查是大公司研发流程的关键一环和重要防线。虽然不能直接提升研发效能,但是能有效避免线上事故的发生,减少程序员不必要的工作量和心理压力。
代码审查CI/CD 即持续集成/持续交付。
在敏捷开发时代,哪怕是一个小团队,每天也会有几次的代码提交,如果长期不合并,可能就会出现代码冲突。
代码冲突因此,持续集成的意义在于,通过每天定时将各个开发人员的代码合并到同一个代码仓库中,以尽早发现代码冲突和错误,帮助团队更紧密地开发协作。
当我们开发完项目,想要发布上线时,要先登录服务器,然后在服务器上拉取代码仓库中的项目代码,然后执行打包命令,最后通过脚本运行项目。
如果只需要在一台服务器上部署,其实还不算太麻烦,但是如果要在几十台机器上部署呢?要一台一台地登录服务器然后重复着上述工作么?
懒人推动世界,这时我们就需要持续交付,将构建部署的每个步骤由人工转变为机器自动操作,原理类似编写了一个自动化构建脚本,在代码合并到仓库时触发脚本的执行,在各机器上自动拉取新代码并打包发布。
目前主流的 CI/CD 平台是 Jenkins
老爷爷,可以配合代码托管平台 GitLab
等实现完全自动化打包、构建、发布,再也不用开发人员一台台登录机器去执行重复的命令了,不仅大大提升了团队研发效率,还保证了发布流程的规范和安全性。
毕竟总有些内鬼程序员借着发布的名义偷偷登录服务器执行 rm -rf *
。
为了在第一时间发现线上项目存在的问题,我们通常会在代码中添加告警逻辑,当某段代码执行异常时通过邮件、短信、微信、电话等方式联系项目负责人。
但有时,我们可能会针对某些指标在一段时间内的统计值设置告警。比如当机器内存占用超过 80% 且持续 5 分钟才告警。这些告警逻辑和业务本身关系不大,如果都写死在代码里,不仅耗时,而且难以维护。
可以在团队内搭建监控告警平台,通过在机器上部署代理或者在代码中使用上报 SDK 等方式来让告警平台统一收集项目运行时的各个指标,比如机器负载、网络负载、异常信息等。
监控告警平台提供配置界面,可以灵活地配置告警规则,比如 1 分钟内收集到 2 个报错就发邮件告警、收集到 5 个报错就发短信等。
完善的监控告警平台还能够对历史告警信息进行管理和详情查看,以及可视化展示各指标图表等。不仅减少了我们开发时的工作量,也能帮助我们更快地分析和排错。
Zabbix 是比较知名的开源监控解决方案,几乎能对任何 IT 基础架构、服务、应用程序和资源进行监控和告警,全面且专业。
Zabbix 监控通常,已上线的项目出现问题时,我们会通过查看日志文件来定位和排查问题。
如果项目比较小,仅仅在单台服务器上部署,那么只需要登录这台服务器,输入命令来查看日志即可。
但团队的项目量级较大时,通常会部署到多台机器上,而且每台机器上的日志量都非常大,以人工的方式一台台登录服务器,然后在数以万计的日志中去找到自己想要的关键信息,是非常低效又恶心的!
杂乱的日志日志不讲武德,可以搭建一个统一的日志平台来治治它们。将各台机器上分散的日志收集到日志平台,然后通过可视化的界面去集中管理和搜索日志,大大提升了查阅日志的效率和体验。
目前比较主流的技术是 Elastic Stack
(Elasticsearch
+ Logstash
+ Kibana
+ Filebeat
) ,使用它可以搭建一套企业级日志平台,轻松管理上百万甚至是上亿的日志数据。
现在很多的项目都采用前后端分离的方式进行开发,前端同学写界面,后端同学提供接口。如果没有一个规范的接口文档,声明每个接口的协议、请求参数、响应参数等,很容易导致前端请求错误。
传统的方式是由后端同学手动编写接口文档,接口改动时,文档也要改动,非常低效且不利维护。
其实,我们可以将接口文档平台化,通过 Swagger
等工具自动生成精美的接口文档网站,开发者还可以在网站上直接测试各个请求,告别了手动编写文档的低效繁琐,提升了开发和协作效率。
测试是对研发质量的保障。
我们写完代码后,不仅要在本地测试,还要在测试环境、预发布环境、线上环境都进行测试验证。项目越大,对测试的要求越高,也就越麻烦。
通常我们会使用 Curl
、Postman
等工具进行接口测试,简单易用。但是有些时候,本地网络(公网)和测试环境(内网)的网络不互通怎么办?
可以在团队内部搭建接口测试平台。提供一个 web 界面,无需下载任何软件,就可以轻松地创建各种接口测试,编写各种测试用例,创建测试计划。最棒的是还能切换不同的测试环境,以及多人共享测试等等。大大提高了测试效率和质量。
天下武功,无快不破。为追求更高的协作效率,可以使用一些即时协作工具。
比如在协作开发同一个项目时,可以使用开发工具 Vscode
的 VS Live Share
插件,支持多人连线,团队成员可以同时对文件进行编辑,甚至还能看到对方的光标!
在多人编写同一个文档或表格时,可以使用腾讯文档,实时看到其他成员的光标位置和对文档的改动,尤其是在开会时,这个功能将非常有用。
腾讯文档使用即时协作平台不仅可以提升效率,还能以最快的速度发现冲突,发现有人正在写烂代码可以直接打字提示他。
团队在开发项目的过程中,肯定会产生很多有用的知识,比如技术选型过程、线上事故的分析处理过程、技术文档、产品文档、业务介绍等。这些知识是团队成员共同积累的财富,日后可能要给其他同学阅读学习,因此必须妥善保存。
以前的做法是,大家把想共享的文件传到一个公共的网盘中,需要时下载到自己的电脑上。当网盘的文件更新时,还要再重复下载,非常地低效。
现在的项目团队,一般都有自己的团队知识库,通常是云端网站的形式,所有的成员可以在知识库中上传想要保存和分享的文档,也可以直接在知识库中编写文档。想要学习知识的同学直接登录知识库网站,搜索文档即可,还能够对优秀的文档进行收藏。
团队知识库不仅能够更好地维护和沉淀团队的知识,还能提升大家编写和阅读文档的效率,更好地进行知识协作共享。
比较不错的在线团队知识库有阿里语雀、腾讯乐享、Wiki、Confluence 等。
语雀知识库有时,我们线上运行的项目进程可能因为某些意外而退出,而且没有被任何人及时发现,这可能会对团队造成巨大的损失。
为了保证线上项目的高可用,可以开启进程监控,当项目进程退出时,自动重启该进程并且向负责人发送告警,一定程度上减少了事故的影响,也省去了手动重启进程的操作。
可以自己编写进程监控脚本,也可以使用一些现成的监控程序,比如 Supervisor
和 Monit
等。
前端监控主要包括对页面的性能监控、错误监控和用户行为监控。对于 C 端项目而言,前端监控非常重要。通过性能监控,可以分析页面性能的不足,优化页面,提升用户体验。通过错误监控,可以在用户进行某些误操作时第一时间通知到项目负责人,并进行相应的处理。通过行为监控,可以获取 UV、PV、IP、点击流等等,从而分析用户的使用习惯,改进产品。
如果没有前端监控平台,开发者要自己收集各用户行为指标,且只能通过不断地测试来分析页面性能的不足,会产生很多额外的工作量。
有很多现成的前端监控平台,比如百度统计、专注错误监控的 Sentry
、腾讯的 Aegis
等,直接申请账号接入即可,省去了自己搭建的麻烦。
在日常开发中,少不了执行定时任务,比如每天检测数据是否正常、定时发送邮件、同步数据等。如果把这些任务都写死在代码中去执行,即使用一些定时任务框架,当任务多了,也会变得难以管理。而且无法控制任务的执行状态,还有可能导致一些单次任务的重复执行,造成风险!
因此,需要统一的任务调度平台来管理任务。可以通过平台界面实时查看各任务的执行情况,还能够灵活地控制任务的启停、执行参数、超时时间等。甚至可以将任务调度到多台机器同时执行。降低风险的同时提升了管理定时任务的效率。
有一些优秀的开源任务调度平台如 Elastic Job
和 XXL-JOB
,可以直接搭建使用。
任何项目都离不开配置,比如数据库连接密码、第三方服务调用地址等。
如果把配置都写死在代码中,或者是项目包里的配置文件中,当配置需要修改时,我们就不得不修改项目文件,提交代码,重新打包,再发布上线,非常麻烦。
而且有些时候,由于多个项目使用了相同的配置,在改动一行配置时,可能要去修改多个项目,不仅麻烦,而且存在漏改的风险。
因此,我们需要一个配置中心来集中管理那些经常变化的、同时被多个项目使用的配置。
比较好用的配置中心有携程的 Apollo
、阿里的 Nacos
等,可以直接在界面上创建和发布配置,还能对配置进行版本控制,灵活地升级和回退。使用配置中心能够提升配置管理的效率,同时避免重复地改动项目的配置文件。
假设我们的项目中有一个功能依赖多个第三方接口,该功能的平均执行时间是 50ms。
/**
* 获取用户详情(依赖三个接口)
*/
function getUserDetail() {
let user = getUserById(); // 得到用户基本信息 10ms
user.account = getUserAccount(); // 得到账户信息 20ms
user.idcard = getUserIdCard(); // 得到用户身份证信息 20ms
return user;
}
结果有一天,这个功能执行超过了 10 分钟!那怎么排查出是哪个第三方接口出现了问题呢?
当出现复杂的调用关系时,我们可以使用链路追踪系统,通过给每个请求环节绑定唯一 id 并上报时间的方式串联起整条调用链路。在链路追踪系统提供的界面可以轻松地查看整个请求的调用过程,能够帮助我们更快地定位请求中的问题,优化接口的性能。
SkyWalking 链路追踪系统以前,团队的项目都是直接部署在服务器上,简单粗暴。但是随着时间的推移,项目会越来越大,最终成长为一个巨石应用。
滚雪球随着云计算、容器、微服务等技术的发展,对于一些大型的巨石项目,我们可以将其拆分为独立的微服务,部署在一个个相互隔离的容器中。容器就像一位少女,轻量、优雅而迅速。
一个项目可能需要同时部署多个容器,我们需要对这些容器进行管理和资源的分配。而容器比服务器的粒度更细,数量可能是机器数的几倍,手动去管理他们是很难的。
Docker 容器因此我们需要容器管理平台,统一管理容器,自动分配资源,并根据容器的资源占用情况进行弹性伸缩,极大地提升运维效率。
K8S(Kubernetes)可以说是最知名的容器管理平台了,很多大公司也都提供容器管理平台的云服务,可以直接接入。
K8S问个问题,如果让你连续开发 5 个电商系统,当你开发第 6 个电商系统的时候,你会怎么做呢?
肯定要将前 5 个电商系统中能用上的代码粘贴过来对吧!
如果你意识到重复开发的麻烦,你就知道有一个中台会多香了,说是提升百倍效率一点也不夸张!
中台的概念近几年来在国内十分火热,可以简单地理解为被很多系统共用的中间件的集合。
中台又分为业务中台、技术中台、数据中台、组织中台等。就拿业务中台来说,就是抽象传统的业务场景,把后台的火药等资源整合成前台打仗需要的炮弹,随取随用。
回到上述问题,我们是不是可以将前 5 个电商系统中用到的技术和工具,抽象成一个中台呢?
中台出现之前,由于团队的分散,我们总是在重复建设一个又一个的轮子。而如今,几乎所有的互联网巨头都在建设自己的中台,比如支付中台、直播中台、电商中台等。如果要开发一个新的系统,我们根本不用从零开始,直接使用中台资源就能很方便地完成,很快啊!
在开发中,我们经常需要编写一些脚本(可以将脚本理解为简单的程序),来帮助我们更快捷地完成某项任务。
比如我们要去重启一个进程,需要执行关闭进程、清理文件、启动进程三个步骤,可能要输入很多行命令才能完成。
do stop
do clear
do start
不妨直接将三个步骤的命令塞到一个 shell 脚本文件里,再次重启进程时,只需要一行命令就行了,很快啊!
./restart.sh
但如果我们想在其他的系统上多次使用这个脚本,怎么办呢?是把编写好的脚本放在自己的电脑上,还是直接扔到服务器上呢?
更好的方式是使用脚本管理平台,团队成员可以将自己编写的各种语言的脚本都发布到该平台上,想在其他系统或服务器中使用该脚本时,直接请求脚本的在线链接,脚本将自动下载、执行和清理。
脚本管理平台尤其适合运维同学使用,某种程度上也是通过自动化提升了效率。
团队开发肯定离不开数据库,并发量高一点还需要使用缓存、消息队列等中间件。
无论是本地开发,还是在测试、线上环境验证,我们都经常需要查看数据库或者缓存里的数据是否正确。最直接了当的方法就是打开小黑框,用官方提供的命令行连接数据库,然后输入查询命令去查看,这也是很多高级工程师现在还在坚持的做法,因为有 B 格。
但是,如果用了分库分表技术,一份完整的数据被分散到多个数据库和数据表中,使用命令行来查看就比较麻烦。因此,我们需要可视化的数据管理平台,比较常用的是本地软件 Navicat
、JetBrains DataGrip
等。
为了更方便地管理数据,团队内部还可以搭建在线的可视化数据管理平台,比如面向 MySQL
数据库的 phpMyAdmin
,开发者无需在本地安装任何软件,直接打开网站,输入密码,就能够浏览和操控数据啦!
提到项目管理,大家可能觉得和技术研发同学没什么关系,其实不然。
通过项目管理平台,我们能够看到每个需求的优先级和排期,可以合理规划自己的研发安排,掌控进度。有重要的信息,也可以贴到需求详情下,相对正式,能够及时同步到所有需求的参与者,规避一些风险。
而如果没有项目管理平台,对需求进度没有一个好的把握,说不定摸鱼就摸过头了。
有很多开箱即用的项目管理平台,比如 TAPD
和 Jira
。
通讯软件是团队沟通协作、高效办公的灵魂,比如腾讯的企业微信、阿里的钉钉、字节跳动的飞书。
这些企业通讯软件早就不只是支持团队即时沟通的工具了,而是大而全的企业办公门户。
像腾讯的企业微信,集成了文档、待办、会议、通讯录、工作台、云盘、电话等办公必备的工具,成员可以通过软件快速地找到并使用这些功能,大大提高了办公效率。还可以在通讯软件中设置机器人,实现业务的自动告警。
以上就是鱼皮分享给大家的锦囊啦。
其实,大厂中还有很多提升研发效能的技术,比如流量回放、压测平台、试验系统、故障演练系统等,这里就不一一介绍了。
此外,每个团队负责的业务不同、情况不同,也都会有提升自己研发效能的独门秘技,要根据实际的场景去选用技术,否则可能适得其反。
希望大家能利用好现有的技术、发掘新的技术,不断提升研发效能,感受技术带来的美好。