Coding CTO 孙宇聪:《人,技术与流程》

我先作一下自我介绍,我是 07 年加入的 Google,在 Moutain View 总部任Google SRE,今年年初回国加入 Codinghtml

在 Google 我参与了两个 Project, 第一个就是 Youtube, 其中包括 Video transcoding, streaming 等,Google 的量很大,每月会有 1PB 级别的存储量,存储,转码后,咱们还作 Golbal CDN ,最大的时候峰值达到 10 TB,咱们在全球 10 万个节点,每台机器都是 24 核跑满状态。而后我从 Youtube 团队离开加入 Google Cloud Platform Team。咱们作的主要工做是管理 Google 全球的机器,大概有 100 万台左右。我离开 Google 以前作的就是 Omega Project,一个集群管理系统,管理 Google 整个云平台的任务调度,协做。可能不少人会说“然并卵”,由于这是都是国内不存在的网站。(笑)前端

从 Google 回来在 Coding 作 CTO,对我来讲也是人生的一个大改变。最近我在知乎看到一个好问题,“从大公司离开到小公司当 CTO 是怎样的体验”,我摘抄了一个好答案:“ 顶着 CTO 的名号,招聘,培训,鼓励程序猿,拉网线,查机房,装系统这都是 CTO 要作的事;讨论方案,推方案,定方案,肯定进度,拖延进度,安抚程序猿,挨老板骂,安抚老板,这也是 CTO 的职务。” 不包括 Coding,而个人工做还包括 Coding,很伤心。(笑)程序员

因此我把这个问题做了归类:docker

CTO 是什么:
第1、他在公司里是一个鼓励师,(我这个形象作鼓励师其实也不是很合适)
第2、多是网管,这个我确实干过,接网线,架服务器,
第3、可能就是受气包,程序员对我很不满,老板对我也很不满。shell

那咱们把这三个角色作为一个对应:数据库

第1、就是研发人员上的管理,包括怎么招人合适,怎样让这些人更好地协做;
第2、是研发技术和研发环境的管理,就是你有了这些人怎样让你们更好地协做在一块儿,更高效地开发;
第3、就是研发流程的管理,怎样让公司这台机器转得更加灵活,顺畅。小程序

那这里我提出了三点要素,人,技术与流程,这是一个公司研发体系中不可缺乏的关键要素。后端

那咱们就先来讲一说人,创业公司都须要全栈工程师。这个全栈工程师长的什么样子呢?通常来讲他就像是一个大侠,踩着白马,手持金枪,什么问题都能解 决,一人单挑好几百人。但是有些时候咱们招不到全栈工程师,咱们就招了一些全干工程师,这也是咱们最近发明的一个词汇。这我的就是他什么都干,写完网站后 写 iOS 最后写安卓。这样的人也很难找,更难的是把这些招来的人员合理地安排在一块儿,合理地组织起来协做。服务器

要想解释 Coding 在研发人员管理上的演变,我首先讲一下 Coding 的服务架构,这是咱们去年 5 月份(初版本上线) 的服务架构,很是简单只有一个 core 程序,通过一年多的演变,如今变成了这个样子。我特地写的字很小,由于不想让你们看清楚,这里面其实错综复杂也不必定对。一个简单的架构是如何一步步演变 复杂的呢? 这里我想先介绍一个康威定律,就是前端工程师

“任何一个设计系统的组织,最终产生的设计都等同于组织以内、之间的沟通结构”。

回想起 Coding 之前的交流方式,老板说"咱们要作一个新的功能",你们就开始把功能拆,前端须要怎么改,要改谁来作,后端要不要改,改的话谁来,服务层,DB 层,测试,部署,每一个人作的事情都不同,每一个人都只作一件事情,每一个人都作流水线上的一个螺丝钉。这样会形成什么状况呢?前端程序员在等后端程序员,什 么时候把接口接上了再开工,后端程序员在等数据库,何时加上这个字段我再开工,测试和部署就更在等了。每次一开项目进度会议时,老板问功能作的什么程 度了,前端说后端没写好接口,后端说数据库还没搞定,常常是这个状态。

那么 Coding 今天采用了一个组织方式,咱们叫他全员全栈,这个全栈的意思和普通意义上的全栈意义不是很同样,这个全栈咱们指的是产品,功能上的全栈。具体是怎么实现的 呢?其实对任何一个比较合格的程序员来讲,语言并非他的瓶颈,也不该该做为他的限制条件。咱们更但愿的是咱们公司里更多的是这种全栈工程师。咱们在作任 何功能的时候,我都会和这我的说你要负责这个功能从头至尾的实现,你须要改前端就改前端,须要改后端就改后端。作这个事情可能刚开始有必定难度,后端工程 师对前端不是很熟悉,前端工程师对后端不是很熟悉,那咱们就用一些其余方法去克服它。这个过程就强迫了组织内部的 Knowledge sharing 。

不少大公司的工程师可能只关心这一小块,好比说前端工程师只写了这一点前端的东西,后端我一律无论,缘由是我不敢动,你们也不让我动。在小公司里 面,每个人都要了解公司的使用的各类技术,咱们共同努力去下降系统的复杂度。 全员全栈是咱们公司的一个战略方向,咱们但愿每一个人都有主人翁的意识,在作需求的时候他能够从前到后一直跟到完,可是想要把全员全栈作好就要作研发环境和 研发工具的调整,接下来咱们讲咱们是如何经过技术手段来协助的。

技术手段在一个研发环境里有三个要素:
第一个就是代码如何管理,如何操做;
第二个就是运行,前端后端代码运行起来要求繁杂,如何调节。
第三点就是你写好以后怎么部署、运维。开发环境和生产环境常常打不通。

为了代码这方面讲好,我先来给你们介绍下在 Google 当码农是一种怎样的体验。Google 最强大的就是他的研发体系通过了 10 多年的积累和锤炼,如今是一套很是高效的体系。那这个“不存在”的公司是怎样管理本身的代码呢?

第一点,整个公司只有一个仓库,一个版本控制系统。这个东西提及来简单,其实很难实现的,不少人以为这个东西好像可行,但他细想难道咱们用的都是 SVN?很明显不是,那 SVN 没有用,Git 也没用,那如何作到只有一个仓库呢?只有一个仓库带来的问题就是全部程序代码都在一个目录下,若是你有一个特别大的硬盘,你把整个公司全都 down 下来,他就是一个目录下的不少子目录,可能几十级子目录,可能整个公司代码有几百 G。那如何同步,管理,操做,这个都是 Google 的独门秘方。

这个有什么好处呢?
第一,你能够看到任何人的代码,你能够看到这个服务是如何实现的,为什么会出现异常,会有什么错误;
第二,它带来 一种更高效的复用方式,好比我写了一个小程序,我 Gmail 的一个程序用了一段 bigtable 的代码,那我直接在代码里引用过去便可,反正你们都在一个目录下,编译环境也同样,有了这个 repo 以后,还有一套编译系统,这个编译系统能作到一键编译任何程序,我运行一个 Gmail 也是一行程序,一个命令是就是编译程序 build 加上 Gmail 的路径便可编译,编译 Go,Python,C++全都是一个命令,不用你去关心底层是如何实现的,运行起来便可。有了这个以后就作到了部署,开发很容易,就是说若是我写业务代 码须要用到一个服务,那我能够很容易地启动这个服务,还能够对该服务作小改动后再次运行起来,这都很容易。

这里说多了你们又会说:道理咱们都懂,可是如何实现呢?

那 Coding 怎么组织咱们的代码呢?由于咱们确实没有 Google 集中式的代码服务,为了调整咱们的代码结构,让你们更好地复用,引用彼此的代码,又由于咱们自己提供 Git 服务,那咱们也是用了 Git 仓库的方式,但咱们每一个项目都是一个独立的仓库,好比咱们前端代码放一个仓库里,后端代码放一个仓库了,各个服务都放在不一样仓库里。

这种方式就产生一个问题,如何同步?

咱们用的是 Google 开源的东西叫 Android repo,你们作安卓开发时可能用到过,这个 repo 是什么意思呢?就是他定义了一个 Workspace,这个 Workspace 有一个固定的格式/结构,而后你统一用 repo 这个工具去 sync,这个 repo 应该到哪一个 commit ,那个 repo 应该到哪一个 commit,全公司都用一样一种 Workspace 的方式,就保证了每一个人看到的代码都是一致的。

作了这个代码结构定义的好处就是:
第一,咱们有代码阅读功能,好比咱们 Coding 的代码阅读能够根据这个 Workspace,能够看到每一个项目的代码,互相引用的状态;
第 二就是质量分析,你能够针对这个 Workspace 作质量分析。这个 Workspace 有一个 repo.sh 这个是一个命令,比较关键的是有一个 default.xml 是这个命令的配置文件,而后你们打开 Workspace 运行 repo sync 便可,它会自动更新每一个组件到最新版本。咱们也鄙视 xml 可是没办法,这个程序就是这么写的,其实很简单,里面主要定义了不少 Project,这个 Project 多是代码仓库的路径映射到了本地的路径,它有一个比较先进的功能就是它能够同时 sync 好几个 Project,就是你一敲 repo.sh sync -g=4 就是开 4 个线程去同步。实践起来这个是很容易的,有了这个东西后打开了这个局面,为你们下一步搞开发环境作了基础铺垫。

工具备了,那咱们真正想要的开发环境是什么呢?

我从 Google 的得来的感触就是咱们想要一个统一的,代码化的,可复制的,可重现的一个开发环境。

第1、每当新同事来公司后,他带着本身的电脑或用公司的电脑,他所用的工具是不同的,环境是不同的,怎样能让公司的代码在本身机器上跑起来实际上是一件比较困难的事情。你们的解决办法多是经过写文档,但这是一件很是痛苦,浪费时间的事情。

第二就是说若是你这个开发环境若是不能够复制,重现,那你的自动化测试怎么作?不能说某我的手动配一下,跑一下,今天挂明天又改吧?

那如何作到统一化的开发环境?咱们作法就是定义了一个通用的接口,我认为这个编译系统的内部实现是无所谓的,怎样均可以,但它的接口比实现要重要一 百倍。你们能够想下若是你每一个程序,每一个组件都是用同一个方法去 Build,去运行,这是一种怎样的体验?咱们定义了一个 build.sh 和 package.sh ,这个 build 就是说我用 Java,Python,Ruby也好,我就定义 build.sh 它最后能产生一个结果能把这个东西 build 好,对我来讲我不关心下面的程序怎么来写,但我只要 build 它,我改了一行代码它可以 build 出新的东西便可。这是咱们如今比较土的作法。

Google 最近开源了 bazel ,它是用 Java 写的编译工具,它实际上就是 build 命令,以后两个反斜杠表明整个 Workspace 的根,而后 coding 是一个 project,server 是 project 的 target。有了这个东西以后其实你 build 任何项目你都考虑的是说它逻辑上的分层而不是物理上的分层,逻辑上的分层就是我要 build 一个 coding server,那这个 coding server 可能里面引用了其余的第三方库,头文件,Ruby 程序,Java 程序都无所谓,我只要说我能 build 一个 coding server 来便可,那这个 bazel 更好的就是它能够自动处理递归依赖,就是你这个 rule 能够依赖到另一个 rule。

有了这个编译后咱们还须要有可复制,可重用的开发环境,那这个开发环境咱们怎么作的呢?
咱们用的是 Vagrant 和 docker。Vagrant 是 VM 的一个管理工具,它能够生成一个新的 VM 来,这个 VM 使用代码来定义的, 而后把每个服务做为一个 docker 服务在 VM 来运行的。

Vagrant 其实作了三件事:
第一件事是它从一个指定的地方下载 Base Box,Base Box 是咱们本身作的,好比说是一个 Ubuntu 镜像加一些本地依赖.
第二就是它支持脚本定义,你能够运行 shell 脚原本定制,再选一个所谓的 Provider,这个 Provider 就是你能够好比说本地是 Virtual Box 的 Provider,远端和不少云厂商能够对接。

进行完这两个操做以后,他就产生了一个 VM,这个 VM 就是一个你能够一键 ssh 进去,它自动把你全部东西都搭配好,这是一个属于你的开发环境,那有了这个东西以后,整个公司能够有一套一致的开发环境,由于是一个 VM,它在哪台机子上运行的方式都同样,全部的依赖库均可以放进去,因此最后的结果就是咱们有一个几G的镜像放在咱们内网里,每一个新同事来了后咱们让他装 一个 Vagrant 或 Virtual Box,而后他敲一个命令,自动把镜像下载,启动,而后一键把整个 Coding 的项目在他的机器上跑起来。

作到了这种可重用的开发环境,咱们还作到了所谓的一键运行。一键运行是和开发另一个层面的东西,它既不关心这个东西是怎么构建出来的,我只关心我 启动这个服务,好比 Coding 开发环境的时候我须要哪些服务,那咱们采用的就是一个本身写的脚原本给 Docker 作编排,这个配置文件里定义了一些 Job,每一个 Job 有一些 image(运行程序的版本、环境变量等)。其实不少时候咱们都是用 go run 命令一键启动不少服务和镜像,达到了咱们刚才说到的统一的代码化的,可复制,可重现的开发环境。

技术工具是我最怀念 Google 的地方,由于这些工具带来不少好处: 首先他鼓励公司内部的协做, 每一个人写程序时不是首先想到本身搞一个小东西出来,咱们更多的时候是去看公司里面其余人作了一个什么东西,它是怎么实现的,能不能引用过来,能不能使用, 能不能把经常使用的类库都抽离出来;
第二它可让新人很快上手,咱们新同事也好,老同事也好,更多的场景是老同事换 Project,之前可能只是使用者,瞬间就能够变成开发者。开发环境的无缝切换无形中下降了不少公司运行的成本。
第 三点就是它让自动化变为可能。刚才咱们是装了 Vagrant 执行一个命令就搞定了,这个东西一样能够做为自动化的东西来实现,好比每次咱们在发 Code Review 时,咱们后台就能够自动启动一个新的 VM,把全部东西下载后运行测试,最后给出改动对错,形成影响等结果,这都是能够自动化的。这点我以为是一个关键点,接下来有了这个环境以后你有了质量分 析,工具后它才可以进行,才能有更多生产力工具接入进来。

最后我再讲一讲流程的管理。

做为一个 CTO,咱们小小的梦想是持续交付更好的软件。老板说你做为一头老黄牛就得不停地往前跑,你也可以按时完成任务。

公司内部有不少实现方式:第一就是 Code Review, 这个流程工具毁誉参半:

第一点就是这个 Code Review 绝对是脑抽检测器,每一个人都有脑抽的时候,评审期就是缓冲期,让你想想你真的是要作这件事情吗?你让别人帮你检查一下是颇有好处的。
第二是Code Review 是一种很好的知识分享的方式。我一我的在写这个功能时我把代码交给别人去看,那另外一我的就会对这个有了解,未来他可能来作你的功能,你换过去作他的工做。鼓励公司内部的知识共享是很重要的。
第三它是一个 idea generation ,你们在作知识共享时很容易发现本身另一个地方也发现了这个问题,我是这么解决的,你为何不这么解决?有什么更好的办法解决吗?Code Review 为促进交流来作这件事。

那 Code Review 作的很差时有哪些方面呢:

第一就是程序员鄙视链,就是老程序员对新程序员很鄙视,说你写的东西太次了,我都懒的看。这个是很很差的一种行为,咱们必定要避免这种东西。咱们作 了一些程序上的要求,好比你每次 Review 时必须把整篇文档都看完,不能说我看了一行发现太烂了不看了,你改好了我再来看,这是不容许的。

第二咱们讲到 Ownership ,就是你在 Code Review 时这个代码属于谁的,咱们讲代码评审是谁写代码谁负责,你写了 rm -rf 你就要对此负责,我看了以后以为你写的有道理,但我没看出 bug, 这是你的问题不是评审者的问题。这是咱们在Google,Coding 实践出来的经验,

第三点就是拥抱变化,就是我原来可能某员工写了一个程序,他以为我写的这个程序实在是太好了,大家不要改,一改我就看不懂了。因此他对任何改动都非 常抵触,这也是错误的,不论在 Google 仍是 Coding ,咱们坚持的一大原则就是说咱们有 Business case 你就能够改代码。你只能去把这个代码写得更好,不能不容许他改,这个是关键,你所写的代码都是属于公司的,那公司怎么能用代码来作更好的事情呢,你要讲清 你的道理,你为何要改这段代码,改了有什么好处,把这个东西变成了技术上的讨论。而不是一个职责,权限上的讨论。

因此我以为这几点是把 Code Review 作的更比如较关键的几点。接下来讲一下 Release Schedule 的问题。

由于创业公司和大公司不同,每一个公司都有本身的 Release Schedule,之前咱们基本靠吼,今天咱们要上线,因此全员就上线,咱们今天要 Release 那就 Release,你若是和老板吼今天上不了线,老板想了想那就算了吧,明天上,并非很严肃。咱们在内部推行的改革是咱们要把冲刺变成长跑,咱们已经创业 一年多了,不能老是冲刺状态了。咱们要变成长跑,可以持续不断地交付高质量的软件,而不是天天上完线后加班到后半夜才把它改好。

方式很简单,就是一周钉死 Release 两次,我说服老板每周两次就够了,三次就多了。Google 一个月才 Release 一次,大项目半年才 Release 一次,咱们创业公司能作到这点已经很好了。一周 Release 两次是什么概念,星期一就要上 Staging 测试环境,星期二就要 Release,星期三又要上 Staging,星期四又要 Release,留给你们周五写写程序,修修 Bug。其实一周 Release 两次也很频繁,可是保证现阶段咱们的转化率,咱们采用了这个方式。把这个东西摊在桌面上来说有什么好处呢,他让你们能够计划我这个功能下周二上仍是下周四 上,你和项目经理打仗的时候有理有据了,他说你看你是星期二上仍是星期四上,程序员说星期二可能搞不定,那咱们星期四来吧,一来二去就把这个冲刺改为了长 跑。

接下来还有一点,咱们要区分 Feture Team 和 Infrastructure Team, Infrastructure Team 也是咱们之前谷歌的一个名词。他讲的是什么意思呢?就是说虽然全员都在作业务逻辑,但咱们必定要抽出必定时间来推行技术演进,你不能说天天我上来就是写代 码,拷贝粘贴,这样搞得你们全部东西都很是混乱。咱们在内部提出了三个点:

第一叫 Coding One,就是咱们公司内部全部的项目,全部的技术,全部的服务都争取用同一套方式来运行。好比说用同一个 Java 版本。这就是一件很难的事情,我以为好多公司都作不到,用同一个第三方类库,这也很难,因此用起来类库都不同,但干起来事情是同样的。这样每一个人代码看 起来都好像是差很少,可是又不同,因此 Coding One 就是解决这个问题,就是 Java 版本,第三方库的版本,第三方库的类型,编译方式,运行环境,启动方式,都应该是同样的。这样会下降不少程序员之间内耗,提升你们的效率。

第二就是 Coding Two,刚创业的时候你们以为咱们都用一台机器,全部东西都跑在上面,这个东西若是坏了那就全挂了。每次更新你们都以为太危险了,咱们仍是后半夜进行吧, 十二点还不够半夜,咱们三四点钟进行吧。由于你这个东西没有备份,没有任何的灰度。咱们叫 Coding Two,之前是从零到一的过程,如今要把从一到二的过程迈过去。从一到二的意思是你这个东西能够是多份的,你这个东西挂了那边还能够继续顶上,这个程序你 作发布的时候你能够先发布给本身用,用好了再发给用户,这才是负责任的方式。

第三点: Coding CI 是我要讲到的最后一点,最后咱们的终极目标,就是所谓的 Push On Green ,意思就是你提交了代码一分钟以内只要全部的测试都跑动过,立刻就上生产环境,你们能够想想在本身公司里能作到这一点吗?若是不能那是为何?你程序员 写了代码,咱们认为程序员写的代码都是善意的,你通过了 Code Review,业务流程上都没问题,他为何不能直接去上生产环境呢?Push On Green 就是终极考验,来考验你这个研发体系能不能作到这一点,若是能作到这一点你才是好的研发体系。

这就是我和你们分享的三点,人,技术和流程,我认为这在一个公司里是一个齿轮同样组合起来的,公司咱们能够说是一个大机器,若是将机器润滑,将齿轮转得更好,结合得更紧密,这就是咱们想追求的目标。谢谢你们。

视频地址:http://v.qq.com/page/d/o/z/d0164k35goz.html
Coding - 让开发更简单! https://Coding.net

相关文章
相关标签/搜索