從在地學習到全域知識#

上一章討論了如何透過無責備事後檢討建立安全的學習文化、發現並修復越來越微弱的失敗信號,以及強化實驗和承擔風險。本章的目標是建立機制,讓在地發現的新學習和改善能被捕獲並全域共享到整個組織,倍增全域知識和改善的效果。

透過這樣做,我們提升整個組織的實踐水準,讓每個人都能從組織的累積經驗中受益。

使用聊天室和聊天機器人捕獲組織知識#

許多組織使用聊天室來促進團隊內的快速溝通,但聊天室也可以用來觸發自動化

這項技術由 GitHub 在 ChatOps 旅程中開創。目標是將自動化工具放到聊天室的對話中間,幫助創造工作的透明度和文件。GitHub 系統工程師 Jesse Newland 描述:「即使你是團隊新人,你也可以查看聊天記錄,看到所有事情是怎麼完成的。就好像你一直在跟他們配對程式設計一樣。」

Hubot:ChatOps 的核心#

GitHub 創建了 Hubot——一個在聊天室中與 Ops 團隊互動的軟體應用程式,只需發送命令即可執行動作(如 @hubot deploy owl to production),結果也會送回聊天室。

將自動化整合到聊天室的好處包括:

  • 所有人都能看到正在發生的事情
  • 新進工程師第一天就能看到日常工作的樣貌
  • 人們更願意求助,因為他們看到其他人也在互相幫助
  • 快速的組織學習被啟用和累積

GitHub 的 Operations 團隊全部遠端工作——事實上沒有兩個工程師住在同一個城市。前 VP of Operations Mark Imbriaco 回憶:「GitHub 沒有實體飲水機。聊天室就是飲水機。」

ChatOps 的實際運作#

Hubot 整合了 Puppet、Capistrano、Jenkins、resque、graphme 等自動化技術。透過 Hubot 執行的動作包括:

  • 檢查服務健康狀態
  • 執行 puppet push 或程式碼部署到生產環境
  • 服務進入維護模式時靜音警報
  • 部署失敗時拉取煙霧測試日誌
  • 將生產伺服器移出輪換
  • 回復到 master 版本

原本常見的問題(如「那個部署進展如何?」、「你在部署那個嗎,還是我來?」)現在很少被問到了。Newland 認為最重要的好處是 Ops 工作變得更人性化——Ops 工程師能夠快速輕鬆地發現問題並互相幫助。

將標準化流程自動化為可重用的軟體#

我們經常將架構、測試、部署和基礎設施管理的標準和流程寫成散文形式,存放在 Word 文件中。問題是:建構新應用程式或環境的工程師往往不知道這些文件存在,或者沒時間實施文件中的標準。結果他們自行創建工具和流程,產出脆弱、不安全、難以維護的應用程式和環境。

我們需要將這些文件化的標準和流程——涵蓋組織學習和知識的總和——轉化為可執行的形式,放入集中的原始碼儲存庫中,讓所有人都能搜尋和使用。

GE Capital 的 ArchOps 案例#

Justin Arbuckle(2013 年 GE Capital 首席架構師)創建了 ArchOps 機制——「讓我們的工程師成為建築師,而非砌磚工。透過將設計標準放入任何人都能輕鬆使用的自動化藍圖中,我們附帶地實現了一致性。」

Arbuckle 總結:「一個組織的實際合規程度,與其政策被表達為程式碼的程度成正比。」

建立全組織共享的原始碼儲存庫#

全公司共享的原始碼儲存庫是將在地發現整合到整個組織的最強大機制之一。當我們更新儲存庫中的任何東西(如共享函式庫),它會快速自動地傳播到使用該函式庫的每個服務,並透過各團隊的部署管線整合。

Google 的單一儲存庫#

到 2015 年,Google 擁有一個包含超過十億個檔案和超過二十億行程式碼的單一共享原始碼儲存庫。這個儲存庫被兩萬五千名工程師使用,橫跨 Google Search、Google Maps、Google Docs、Gmail、YouTube 等所有 Google 產品。

其價值在於工程師可以利用組織中每個人的多元專業。Rachel Potvin(Google 工程經理)告訴 Wired:每個 Google 工程師都能存取「大量的函式庫」,因為「幾乎所有東西都已經做過了。」

共享儲存庫中應包含的內容#

不僅是原始碼,還有其他編碼知識和學習的產物:

  • 配置標準(Chef recipes、Puppet manifests 等)
  • 部署工具
  • 測試標準和工具(包括安全性)
  • 部署管線工具
  • 監控和分析工具
  • 教學和標準文件

Randy Shoup 描述:「Google 防止失敗最強大的機制是單一程式碼儲存庫。每當有人 check in 任何東西,就會產生新的建置,使用所有東西的最新版本。所有東西都從原始碼建置而非在運行時動態連結——永遠只有一個正在使用的函式庫版本。」

解決版本碎片化問題#

考慮一個組織在生產環境中運行八十一個不同版本 Java Struts 框架函式庫的真實案例——除了一個以外全都有嚴重安全漏洞。維護這些版本造成巨大的營運負擔。單一原始碼儲存庫加上自動化測試,可以大幅解決這個問題,讓團隊安全且有信心地遷移到新版本。

利用自動化測試作為文件和實踐社群#

當共享函式庫在整個組織被使用時,確保每個函式庫都有大量的自動化測試,使這些函式庫成為自我文件化的,向其他工程師展示如何使用它們。

如果我們實施測試驅動開發(TDD),這個好處幾乎是自動的——自動化測試在程式碼之前編寫,將測試套件變成系統的即時、最新規格說明。任何工程師只要查看測試套件,就能找到如何使用系統 API 的可運行範例。

理想情況下,每個函式庫都有一個單一負責人或團隊支援它,代表知識和專業的所在。我們應該(理想上)只允許一個版本在生產環境中使用,確保生產中的內容利用了組織最佳的集體知識。

為了更快地傳播知識,我們還可以為每個函式庫或服務建立討論群組或聊天室,讓有問題的人能從其他使用者那裡得到回應。

透過編碼化的非功能需求為營運而設計#

當開發團隊參與生產事件解決活動時,應用程式會越來越適合營運。我們可能會識別出一組非功能需求(non-functional requirements),想要整合到所有生產服務中:

  • 應用程式和環境中有足夠的生產遙測
  • 準確追蹤依賴關係
  • 服務具有韌性且能優雅降級
  • 版本之間的向前和向後相容性
  • 歸檔資料以管理生產資料集大小
  • 搜尋和理解跨服務的日誌訊息
  • 追蹤使用者請求通過多個服務
  • 使用 feature flag 的簡單、集中的運行時配置

將可重用的 Operations User Stories 嵌入開發#

當 Operations 工作無法完全自動化或自助服務時,我們的目標是讓這些重複性工作盡可能可重複且確定性。我們透過標準化所需工作、盡可能自動化,並記錄工作來實現。

對於所有重複性的 Ops 工作,我們理想上應該知道:需要什麼工作、誰需要執行、完成步驟是什麼等。我們可以創建定義良好的「Ops user stories」,代表可在所有專案中重用的工作活動(如部署、容量規劃、安全等)。

確保技術選擇有助於實現組織目標#

在服務導向架構中,小型服務團隊可以用最適合其需求的任何語言或框架來建構服務。但有時候,專業知識只存在於一個團隊中,只有該團隊能做出變更或修復問題,形成瓶頸。

我們的目標是識別那些:

  • 阻礙或減緩工作流動的技術
  • 不成比例地產生大量非計畫工作的技術
  • 產生大量支援請求的技術
  • 與我們期望的架構成果最不一致的技術(吞吐量、穩定性、安全性、可靠性、業務連續性)

Etsy 標準化技術堆疊的案例#

2010 年,在一個近乎災難性的假期旺季之後,Etsy 團隊決定大幅減少生產環境中使用的技術數量,選擇少數幾個全組織能充分支援的技術。他們將整個平台遷移到 PHP 和 MySQL——這主要是一個哲學決定而非技術決定,目的是讓 Dev 和 Ops 都能理解完整的技術堆疊。

HP 的 CIO Ralph Loura 將他們的做法描述為建立「浮標,而非邊界」(buoys, not boundaries)——標示出安全且受支援的深水區域,但允許人們在遵循組織原則的前提下探索浮標以外的領域。

結論#

本章描述的技術使每個新的學習都能被納入組織的集體知識中,倍增其效果。我們透過積極且廣泛地溝通新知識(如聊天室)以及透過技術(如 architecture as code、共享原始碼儲存庫、技術標準化等)來實現。透過這樣做,我們提升的不僅是 Dev 和 Ops 的實踐水準,而是整個組織的水準。