事後析誤文化¶
在本書描述中,事後析誤是一個在 Google 中非常重要的文化(事後析誤並不是什麼新科技,而是文化)。 其核心的概念是:析誤過程中不要帶著責備。 好的事後析誤文化,會讓失誤減少,工作更高效和快樂,並減少重複性錯誤,加快錯誤恢復。 而本篇的重點則是要傳達一個訊息:推廣事後析誤文化是可行的!
以下文章將分為三大塊:
- 比較壞的和好的事後析誤文件
- 建立強健的事後析誤文化和辨識一些可能造成破壞的跡象
- 一個工具和樣板幫助開始建立
邊緣快取和代理器的失能¶
雖然 Google 大部分的伺服器都位於自己管理的資料中心,但仍會在一些地區使用租借的資料中心, 使用託管服務(Colocation centre)建立快取(cache)和代理器(proxy), 而這類的機器在 Google 內部,稱其為 衛星(satellites)。
Google 對於維運設備的運行,大部分都是依靠自動化的, 包括新機器的軟體安裝、退役、版本升級、流量洩流(drain)等等。 其中退役時的自動化稱其為 磁碟抹除(dsikerase), 一旦機器被抹除,儲存的所有資料將無法再被獲取。 而這端自動化的邏輯大致如下:
// 得到指定資料中心(satellite)的所有在線機器
const machines = getActiveMachinesFrom(satellite);
// 透過 `filter` 把該指定資料中心的機器(而非所有資料中心的所有機器)進行退役
sendToDecom({
candidates: getAllActiveMachines(),
filter: machines,
});
當維運人員進行日常的退役工作時,自動化執行結果得知有錯(然而實際上卻已經正確進行退役), 這時維運人員為了除錯,再一次的執行這個自動化腳本:
// 因為上一次把所有機器都退役了,所以這裡會得到空的陣列
const machines = getActiveMachinesFrom(satellite);
// `filter` 收到空陣列後,會直接選用所有的 `candidates` 而非空陣列
sendToDecom({
candidates: getAllActiveMachines(),
filter: machines,
});
由於 filter
是空陣列,全世界所有衛星內受託管的機器都被進行磁碟抹除,
因為衛星內的機器被判定為失能,全世界所有的流量都被導流進 Google 自己維護的資料中心。
幸虧當初的容量規劃讓 Google 有能力承載這些流量, 這次的事件雖然耗時了兩天才把所有資料中心的伺服器恢復正常,但只造成些微的潛時(latency)上升。 並且在事後數週進行健全的監控和建立阻斷器, 並確保該自動化流程是冪等的(idempotent,重複執行不會互相影響)。 三年後,類似的事件導致部分衛星的伺服器失能, 而三年前的整治手段大大降低了該事件的爆炸半徑和恢復時間。
接下來,我們就來撰寫看看這次事件的事後析誤文件,並比較兩個不同文件的差異。
壞的事後析誤文件¶
- 事件所有者:楊一@、李二@、陳三@、王四@
- 事件審閱團隊:衛星基礎設施維運團隊@
- 狀態:完成
- 事件發生日:2014-08-11
- 文件發布日:2014-12-30
事件概要¶
- 影響:所有衛星機器都被磁碟抹除,並導致所有 Google 的邊緣運算能力失效。
- 根因:王四@ 忽略執行後的檢查,直接重複執行自動化的操作,進而觸發錯誤。
狀況總結¶
- 持續時間:40 分鐘。
- 影響產品:邊緣運算資源。
- 影響比例:所有邊緣運算。
- 使用者影響:所有經過邊緣運算的請求潛時拉高。
- 收益影響:有些廣告因為潛時拉高,沒有正確投放。
- 發現於:監控告警。
- 復原於:透過人工復原邊緣運算,持續導引流量。
背景(非必要)¶
無。
影響¶
- 使用者影響:潛時拉高。
- 收益影響:有些廣告沒辦法投放。
根因和觸發點¶
叢集的自動化操作不是冪等的。 程式碼本身有避免部分機制重新執行的限制,但是無法阻止使用者重複執行程式本身。 荒唐的是沒有任何文件說明這個陷阱,導致團隊成員大部分都任何重複執行是可被接受的。
這便是在執行日常退役時,發生的錯誤原因。 我們正準備把機器進行替換時,王四@ 完全忽略了上一次操作已經正確執行, 因為他的不小心導致進一步觸發該陷阱。
復原操作¶
無。
學到了什麼¶
- 我們做對了
- 告警成功觸發;
- 事件管理機制正確運行。
- 我們沒做好
- 團隊(特別是楊一@、李二@)竟然沒有撰寫文件告知大家不要重複執行程式碼;
- 待命小組沒有成功阻止磁碟抹除的自動化腳本從單一叢集擴大到全部叢集,並且已經不是第一次反應這麼慢了。
- 幸運的事
- 核心運算資源能正常處理全球的流量,我不敢置信我們成功的避免災難發生!!
後續優化¶
項目 | 種類 | 優先度 | 負責人 | 票 |
---|---|---|---|---|
讓自動化更好 | 緩解 | 2 | 李二@ | |
優化告警 | 偵測 | 2 | ||
陳三@需要學習如何跨資料中心的交付協議 | 緩解 | 2 | TICKET-123 | |
教育訓練避免錯誤執行指令 | 預防 | 2 |
詞彙表¶
無。
為什麼這份文件寫得糟¶
災難的價值在於好的事後析誤,正因如此,我們花時間去撰寫這份文件,將變得至關重要。 閱讀者在看這份文件時,應該要清楚事件的脈絡,更重要的是能從事件中學到些什麼。
接下來我們分析一下為什麼上一份文件寫得很爛。
背景描述的匱乏¶
本次事件有幾個專有名詞, 例如 衛星 代表用來處理邊緣運算的機器、磁碟抹除 代表自動化運行的腳本。 如果你需要提供一些背景知識,請額外增加一些段落來說明,例如「詞彙表」或「背景知識」。
一個缺乏清楚概絡的文件,不只會讓人看不懂, 甚至會讓人選擇忽略這份文件,進而把能從事件學到的東西直接歸零。
關鍵細節的忽略¶
很多段落只有高層次的概觀,缺乏重要的細節,例如:
狀況總結中,我們無法從這份文件得知事件的影響範圍,如果影響範圍是多個產品,請明確給出相關的數值。 這份文件中只有持續時間是數字,如果沒有相關數值,請盡量給出個估計, 畢竟 沒有正確的爆炸半徑,就無法正確評估是否修復完成。
根因和觸發點是事後析誤文件中非常重要的一點。 在這份文件中,只有看到一小段落,缺乏足夠細節讓人能夠有機會思考其中的改進點。
我們通常能在復原操作段落中找到發生了什麼,怎麼被緩解以及使用者是怎麼被影響的, 然而這份文件卻完全空白。
後續優化的貧乏¶
後續優化(Action Items, AIs)有幾個面向去評斷他的好壞,例如:
- 大部分的優化都是緩解型或預防型的,在預防過程中,不要期待人類不會犯錯,應該考慮的是如何
「讓人類無法在此地犯錯」,其中冪等就是一個很好的特徵。
讓我們假設未來參與維運本服務的人員,都和事件中的我們一樣愚蠢。
— Dan Milstein,Post-Mortems at HubSpot: What I Learned From 250 Whys - 每個優化都是相同的優先程度,會讓這個欄位失去意義。
對客戶來說,一個沒有後續優化的事後析誤文件,等於沒有文件,所以任何一個會影響客戶的事件, 都應該要有至少一個優先程度為為 0 或 1 的改善項目。 - 勁量避免使用「讓他更好」、「優化」等泛化的詞彙,會讓人無法分析該優化的完成度。 - 如果沒有票去追蹤相關優化,這些改善都很容易被遺忘。
指責型的敘述¶
明確說明何人在何時何地犯錯看起來是個合理的撰寫文件方式,但是這會讓這些人更害怕犯錯, 進而選擇掩蓋錯誤,最後讓於本次事件的根因或觸發點被錯誤解釋。 常見的範例可能是:
- 把團隊成員指明出來負責,應該以團隊為單位去歸咎事件;
- 要求特定成員的教育訓練。
誇張的用詞¶
例如:不敢置信、很荒唐地。
事後析誤文化是一個事實導向的文件,也當然允許個人的評論和質疑, 它應當是提供一個空間讓多人多角度且互相尊重地去討論本次事件。 但是過多的情緒言論會影響其他人進來參與的意願,好的方法應當是以資料為佐證去闡述相關論點。
事項的歸屬人員¶
這個事後析誤文件找不到應該由哪個人負責撰寫、追蹤以及回答其他人的疑問, 而是提供了四個人的名字,讓大家去猜。
後續優化項目缺乏明確的負責人,這會讓這些改善很難進行後續追蹤。
文件的閱讀人員¶
在這份文件中,只允許團隊內部人員查看,Google 建議事後析誤文件是允許公司內部所有人員查看的。 因為事後析誤文件的價值就是讓越多人從中學到越多事情越好。 更有甚者,也可以把這份文件公佈給公司外部人員查看, 因為一個被妥善撰寫且誠實的文件也是一個恢復大家對公司信任的好方法。
文件發布的延宕¶
這份文件的發布已經是事件發生後的好幾個月了,團隊成員對於本次事件的記憶已經模糊, 很可能在撰寫上出現瑕疵。
好的事後析誤文件¶
接下來的範例是實際上存在的文件,雖然會把一些敏感資料藏起來,但足以檢驗何為好的事後析誤文件。
- 事件所有者:
- 文件撰寫:楊一@、李二@
- 資料中心自動化腳本:陳三@
- 網路管理:王四@
- 系統管理:劉五@
- 事件審閱團隊:所有工程員工@google.com
- 狀態:完成
- 事件發生日:2014-08-11,週一,17:10 to 17:50 PST8PDT
- 文件發布日:2014-08-15,週五
事件概要¶
- 影響:
- 前端請求被丟棄;
- 一些廣告沒辦法播放;
- 所有被衛星所服務的應用,其潛時都被拉高並持續接近兩天。
- 根因:設備退休相關的自動化有錯,導致並非特定機櫃的設備進行磁碟抹除。 這讓全世界所有衛星的設備都被排進退休流程,最終其能提供的前端快取都無法運作了。
狀況總結¶
- 持續時間:
- 主要於 08-11,週一,17:10 到 17:50 PST8PDT;
- 重新建置和潛時拉高的狀況持續到 08-13,周三,07:46 PST8PDT,並於此時關閉事件。
- 影響產品:GFE(前端基礎設施),特別是使用衛星的地區。
- 影響比例:所有透過衛星服務的全球性流量(一般來說約為 60% 的總流量)。
- 使用者影響:
- xx 的前端流量被丟棄並持續 40 分鐘(期間內平均的 QPS 為 xx,佔總流量的 xx%);
- 所有有被衛星設備服務的應用,其潛時都被拉高並持續兩天。
- 收益影響:實際收益影響目前不可知。
- 發現於:Blackbox 監控,團隊收到幾乎全球所有衛星設備的錯誤訊息:
satellite-a12bcd34 服務太多失敗 HTTP 請求
- 復原於:災難發生後,所有流量迅速被導流至 Google 擁有的前端叢集中,但是相關潛時都被拉高了。
背景(非必要)¶
如果你不熟悉 Google 前端流量的服務方式和其底層的自動化機制,請先參閱詞彙表。
影響¶
以下將說明各個面向的影響。
使用者影響¶
- xx 的前端流量被丟棄並持續 40 分鐘。期間內平均的 QPS 為 xx,佔總流量的 xx%。 我們的監控系統顯示出被丟棄的流量其實要更大,這是因為部分衛星其實仍然有在服務, 但是被監控認為失能,所以就會有數據上的落差,我們會在復路上說明我們怎麼估計這個流量的。
- 所有依賴於衛星的應用其潛時都在這兩天內被拉高:
- 接近 Google 維護的核心運算資源的國家有約 xx 毫秒的 RTT 高峰;
- 其他較依賴於衛星設備的國家(例如,澳洲、紐西蘭、印度)則有 xx 毫秒的高峰。
收益影響¶
有部分廣告沒有被投放,實際收益影響目前不可知:
- 圖片和影片:根據日對日的資料顯示有很大的錯誤比例差距,我們估計實際收益損失約落在 xx 到 xx%;
- 搜尋:xx 到 xx% 的錯誤落在 17:00 到 18:00 之間,同樣有很大的日對日差距。
團隊影響¶
- 流量維運團隊用了所有人力並花了約 48 小時來完成修復;
- NST(某個服務)有高於水平的負載中斷,因為他們需要允許更高的限流進入核心運算資源;
- 因為快取命中的下降,一些服務有更高的回應時間:
- 例如,請查看這個聊天記錄(某連結)來知道有哪些服務;
- 這些服務看到快取命中率從 xx 降到 xx%。
事件追蹤連結¶
某個連結導向事件追蹤系統。
根因和觸發點¶
長期存在於執行驗證機制的錯誤,導致編號 a12bcd34
的設備在退役過程出錯,
這個錯誤讓退役機制不再受限於指定設備,而是所有的衛星設備。
至此,在人工介入暫停自動化機制前,現有大部分的衛星設備都被執行了退役,並進行磁碟抹除。
流量團隊提供了 ReleaseSatelliteMachines
這個 API,他會進行三個階段的操作:
- 搜尋該設備擁有的機櫃,例如
a12bcd34
裡有一個rack123
機櫃; - 搜尋所有位於該機櫃的機器,例如
rack123
對應於machine1
、machine2
等等; - 把這些機器進行磁碟抹除。
因為缺少檢查,所以這個操作並不是冪等的。 如果有一個機櫃已經在上次操作進行磁碟抹除,第二項操作得到的機器就會變成空陣列。 當空陣列傳進第三項操作時,就會變成把所有機器進行磁碟抹除。
這個危險的程式邏輯已經存在一段時間了,但是因為團隊在執行完一次操作後, 會在 UI 上顯示 run once 這個通知,代表他已經成功被執行,不需要再執行了。 但這個 run once 並沒有告知使用者,當你再執行一次,會發生什麼事, 這也進一步讓叢集重啟團隊在手動觸發第二次退役操作時,觸發了這個錯誤。
時間線和復原操作¶
時間線和操作在這裡被隱藏了,但實際的文件中這個資訊是一定會有的。
學到了什麼¶
我們做對了¶
- 核心運算資源能夠承載所有流量(詳見下個段落),即使所有邊緣運算都失能, 這讓流量團隊可以在較低的壓力下進行復原工作;
- 當邊緣運算失能時,自動化的導流機制正確地把流量導到核心的資料中心;
- 衛星在退役過程是快速且有效率的,雖然這有代理人混淆的風險;
- 事件成功透過 OMG 觸發 IMAG 並且該工具成功證明對於事件追蹤和跨團隊溝通的價值。
我們沒做好¶
關於失能的部分:
- 流量 Admin Server(管理服務)沒有正確驗證指令, 且所有指令應該都要冪等的或至少當重複執行時是失效安全的;
- 機器資料庫(MDB)並沒有限制跨資料中心的所屬驗證; (雖然該人員只允許對 A 地區的操作,但是透過 MDB 卻可以做到全域的操作,即代理人混淆)
- 退役操作流程並沒有交叉比對退役請求和當初申請的範圍是否相當;
- 退役操作流程沒有限流,當開始退役時,所有操作都是馬上執行,並沒有任何緩衝;
- 一些對外的流量因為目的從邊緣運算機器轉到其他區域,導致有一段時間的網路壅塞,而該壅塞直到邊緣運算恢復後才被復原。
關於復原的部分:
- 重新安裝機器是緩慢而不可靠的,其是透過 TFTP 去傳遞資料,而當專線正處於繁忙時,這個操作是緩慢的;
- Autoreplacer(自動替換機制)的基礎設施是沒辦法處理同時要建置 xx 個節點的,
為了加速自動化建置,需要許多人力投入進去手動建置,以下是幾個造成緩慢的因素:
- SSH 超時會讓自動替換機制在一些較遠的節點上出現不穩定的狀況;
- 緩慢的核心版本升級,即使核心版本已經達到指定的版本;
- 核心的邏輯會限制併存操作,導致同時最多只能設定兩個機器;
- 自動替換的奇怪外顯行為增加了對其操作的困難性。
- 針對過多節點(25%)正進行退役行為的監控,在節點達到 23% 時並沒有告警, 但是在漲到 29% 時發出了告警,但這兩個數字之間差了 30 分鐘;
- 能夠進行安裝的工程人員很少,這造成適時調整的困難和復原的緩慢;
- 透過最高權限(superuser)進行人工安裝造成不同機器的狀態出現差異,這增加了後續要進行打掃的痛苦。
幸運的事¶
- 核心運算資源和邊緣運算的管理方法有非常大的差異,這導致在邊緣運算發生問題時,並沒有影響核心運算;
- YouTube 的 CDN 也有著不同的基礎設施和管理手段,這導致事發時,該產品的超大流量並沒有進一步拖垮核心運算資源。
後續優化¶
由於本事件的廣泛影響,我們將優化拆分成五個面向:
- 預防和風險的教育
- 緊急狀況的回應
- 監控和告警
- 邊緣運算的供給
- 雜項
優化內容 | 種類 | 優先度 | 所屬人員 | 票號 |
---|---|---|---|---|
審計所有會讓正常機器變成失能的系統 | 調查 | P1 | 陳三@ | BUG123 |
開票去追蹤 BUG123 列出的系統是否有阻擋錯誤輸入 | 預防 | P1 | 陳三@ | BUG124 |
拒絕任何單一操作可以跨限域去執行 | 緩解 | P1 | 楊一@ | BUG125 |
管理系統需要額外檢查去避免針對超過 xx 的節點進行操作 | 緩解 | P1 | 王四@ | BUG126 |
管理系統需要去問安全檢查系統是否執行允許退役工作 | 預防 | P0 | 李二@ | BUG127 |
管理系統拒絕那些應該要給值卻沒值的操作 | 預防 | P0 | 許七@ | BUG128 |
優化內容 | 種類 | 優先度 | 所屬人員 | 票號 |
---|---|---|---|---|
確保從核心對外的流量不會過載 | 復原 | P2 | 蘇六@ | BUG129 |
確保退役流程的問題被註記在緊急停機文件和災難升級聯繫文件中 | 緩解 | P2 | 李二@ | BUG130 |
新增一個紅色按鈕來中斷停機流程 | 緩解 | P0 | 楊一@ | BUG131 |
優化內容 | 種類 | 優先度 | 所屬人員 | 票號 |
---|---|---|---|---|
監控目標的安全性檢查要拒絕那些無法回溯的異動 | 緩解 | P2 | 王四@ | BUG132 |
當超過 xx% 的機器被下線,發出告警。機器的退役過程從 16:38 持續到 17:10 | 偵測 | P1 | 蘇六@ | BUG133 |
優化內容 | 種類 | 優先度 | 所屬人員 | 票號 |
---|---|---|---|---|
透過 HTTPS 使用 iPXE 來提升重新安裝的效率和速度 | 緩解 | P2 | 王四@ | BUG134 |
優化內容 | 種類 | 優先度 | 所屬人員 | 票號 |
---|---|---|---|---|
透過既有工具審閱管理系統的程式碼 | 復原 | P2 | 蘇六@ | BUG135 |
安排 DiRT 測試:磁碟抹除後復原機器;YouTube 的 CDN 也做同樣的事 | 緩解 | P2 | 許七@ | BUG136 |
詞彙表¶
Admin Server¶
一台 RPC 的管理服務,允許自動化機制針對 GFE 執行一些維運行為。最常見的操作就是啟動或關閉節點。
Autoreplacer¶
自動替換機制是用來管理機器的服務,它允許透過操作來設定機器、資料移轉、機器重啟等操作。
退役¶
退役機器是一個牽涉到許多團隊的流程。
磁碟抹除¶
一個會關係到軟硬體的行為,用來讓硬體設備在退出 Google 的資料中心前,進行安全的抹除。 磁碟抹除是退役流程中的一環。
GFE(Google Front End)¶
前端基礎設施執,在流量進到 Google 核心的資料中心前,負責接收流量或邊緣的設備群。
IMAG(Incident Management At Google)¶
一個嘗試建立標準化和一致性方法來處理所有事件的專案,從系統失能到天然災害,並整合相關有益的回應。
MDB(Machine Database)¶
一個納管所有機器狀態的資料庫。
OMG(Outage Management at Google)¶
一個提供事件管理和儀表板的工具,用來集中追蹤和管理所有正在處理的事件。
衛星系統¶
小且便宜的機器群,用來服務非影片的外部或邊緣的網路流量。 幾乎所有的線上基礎設施都可以不依賴他而進行運作。 YouTube 的影片流量不是受到他服務的,而是另外有個專門的 CDN 來處理,也因此不受本次事件影響。
附件¶
為什麼 ReleaseSatelliteMachines
不是冪等的?
隱藏相關回答
當 Admin Server 執行的操作是針對所有衛星設備時,會發生什麼事?
隱藏相關回答
當發生災害時,實際上錯誤的 QPS 是多少?
隱藏相關回答
IRC 的日誌
隱藏相關回答
圖表¶
更優的潛時 — 衛星系統實際為我們做了什麼?
根據此次事件,在靠近核心資料中心的地區,衛星系統降低了 xx 毫秒的潛時; 在距離較遠的地區,則降低了 xx 毫秒的潛時。
隱藏的圖片
核心和邊緣承載的量
下圖中很好的展示了重建的過程。 邊緣重新恢復到承載 50% 的量,花了 36 個小時;回到正常水位又再額外花了約 12 個小時。
流量轉移到核心時的封包狀況
圖片中,根據不同地區顯示掉封包的累進比例。
當事件發生後,除了一些短暫的高峰,整體來說掉包的高峰落在當邊緣運算完全失能的時候。
隱藏的圖片
人工和自動化復原比例
隱藏的圖片,說明人工和自動化復原的比例
為什麼這份文件寫得好¶
一份好的事後析誤文件要能快速、精準、和善的。
清晰的段落¶
各個段落的內容分段清楚而富含細節,例如:
- 詞彙表,讓更多人有機會參與;
- 後續優化,這個大型事件有很多優化空間,透過分門別類讓他更容易分派工作和權衡;
- 可量化指標,足夠的數據和圖片,並且附上原始資料的連結。
具體的後續優化¶
- 權責歸屬,明確指定所屬者和票號;
- 優先程度,分清優先程度來有效追蹤這些優化實作;
- 量化實作,例如設計新的告警檢視是否超過 xx% 的機器下線了;
- 分類屬性,例如預防性和緩解型。
不責怪單一人員的行文¶
文件專注在系統設計的不完善,而非人為操作的失誤:
- 我們沒做好,並沒有人員被點名並責怪;
- 根因和觸發點,專注在「什麼東西」沒弄好,而非「誰」沒弄好;
- 後續優化,專注在改善服務,而非改善人員。
足夠的深度和廣度¶
並非專注在特定團隊的改善,而是透過多的服務的角度來思考:
- 影響,這段在很多不同角度中提出說明,讓他影響範圍更客觀;
- 根因和觸發點,從系統到程式碼的實作,提供足夠細節的說明;
- 資料導向的總結,所有的總結都是基於事實和資料,並提供原始資料的連結;
- 附錄,提供更多圖片讓非專業人員能快速理解差異和影響。
文件撰寫快速¶
文件撰寫的越早,越精準,這是因為人們的記憶更鮮活。 除此之外,當事件發生後,所有受影響的工程、主管、投資者, 都會想要確保事件真的被解決了,否則隨著時間推進,他們會對你的產品有一些各自的想像和不信任。
這篇事後析誤文件在事件發生後的不到一個禮拜,就完成了。
精準的描述¶
這是一個大型事件,理論上會有很多的資料:原始資料、系統日誌記錄、人員通訊紀錄等等。 這篇文件透過總結、圖片、和連結來讓 冗贅性 和 可讀性 之間達到平衡。
實際導入的注意事項¶
理想上,高階領導會促進事後析誤的發展,這裡列出一些注意事項:
可以強化的做法¶
展現無責備的精神¶
例如:
你是個主管,為什麼沒有確保大家都完成復原設備的操作訓練?
可以調整成
也許可以在進入待命小組前,先要求這些人員完成這項訓練, 或者在狀況持續時,鼓勵待命小組把事態升級,讓更多人進來關注這件事, 畢竟我們關心的不是事件的等級或多寡,而是使用者無法操作系統的感受。
獎勵事後析誤的產出¶
推力、拉力,好的獎勵會讓這文化更容易推廣,以下是可以獎勵的行為:
- 優化作法的成功執行;
- 從事件中得到的東西向企業內部橫向的推廣,例如某種優化設定;
- 實際進行事件處理的時間減少的比例,例如今年只用了兩週在處理事件;
可以進行的獎勵可能有:
- 讓事件的參與人有機會變成該類型事件的意見領袖,例如 「你可以和小明討論看看,他上次才和某團隊一起撰寫了這類型事件的析誤文件,他應該會給你一些意見」;
- 遊戲化,例如賞金獵人,統計各個人員或團隊事件處理的次數,並有排行榜等等。
開放式的精神¶
這也是一種間接的獎勵,有一些做法可以參考:
- 避免單一團隊或人員撰寫,容易失去客觀性;
- 鼓勵非參與人員的回饋;
- 把事件摘要放進內部通訊管道,例如 Teams 或 Slack;
- 跨團隊的檢討和審查,甚至非官方的閱讀社團;
- 讓新進員工能參與進來,例如練習賽;
- 每週事件會議,共同審視過去一週的事件。
壞味道¶
當企業在實施這個文化時,很可能會失敗或變質,而這個原因有時是很微妙的,可能的徵狀有:
- 員工避免參與事後析誤,例如「哇,你有聽說這次事件嗎?」「是啊,真慘,他們正在寫文件」「幸好不是我」;
- 實作人員的不認同,例如「我知道公司鼓勵不責備,但這裡只有我和你,為什麼你不在事前去接受那些改善意見?」 可以改成「事前應該會有一些徵兆,我們可以來討論一下為什麼我們忽略了這些徵兆」;
- 缺乏時間撰寫,好的事後析誤文件是需要時間撰寫的,透過一定程度品質的文件,來教育未來的所有團隊。 替撰寫文件排優先順序、追蹤進度和審閱結果,最重要的是要給予團隊時間完成事件的相關後續優化。
- 重複性事件,如果類似的事情反覆發生,這是一個好的徵兆去進行深度研究。
嘗試集合各個事件的協作者,並把各個文件拿出來比較,有幾個切入點:
- 後續優化是否花了太多時間?
- 功能性的開發是否影響穩定性優化的調整?
- 優化是否在一開始被正確提出?
- 服務是否太過老舊,以至於重構困難?
- 是否在嚴重的傷口上,貼上 OK 蹦?
工具和平台¶
雖然不可能完全自動化,但是這些工具能讓文件加速且精準。
- 文件模板,讓公司其他人能快速找到他們想要的,同時模板建議允許進行一些客製化:
- Google 內部是使用 Google Docs,因為允許共編,且允許客製化;
- 透過 Google Apps Script 進行一些自動化,例如選擇內部員工時。
- Google 發展出來的 checklist:
- 災難影響範圍的完整遍歷;
- 根因的清晰了解,並依此發展優化(Five Whys);
- 優化項目是經過技術主管的批准和審查。
- 資料庫的選擇(目前都沒有開源,需要花時間調查,例如 Zalando 的 Sunrise):
- 透過搜集而來的資料,讓下次建立析誤文件能夠更快速更自動化;
- 建置一個可以有效追蹤後續優化的面板;
- 分析並畫成圖來直觀表達哪些地方還不夠穩定(一個公司服務地圖,並標注紅色來表明這段不穩)。 並根據一些指標,例如:次數、爆炸半徑、持續時間、偵測時間、復原時間,來進行當月的績效評估。
以下列出一些有用工具:
- PagerDuty 的 postmortem template;
- 部落客在 GitHub Gist 撰寫的 postmortem 範例;
- 在 stackoverflow 上的一些討論:postmortem 需要哪些段落
結論¶
歷程大致是: 從小的專案開始; 透過工具和模板來寫好報告; 確實依據報告來做實踐和修正; 最後鼓勵且公開把這些報告分享給大家。
相關平台的建置勢在必行,但是需要一些好的範例、模板、自動化工具例如 GPT 來加速撰寫和精準定位, 更重要的是延伸優化項目。