我先作一下自我介紹,我是 07 年加入的 Google,在 Moutain View 總部任Google SRE,今年年初回國加入 Coding 。html
在 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