Du Spirit

No more calculation 症狀 (Symptom):喜歡用公式換算,像是點數換算時數,時數換算點數,換算可完成的 story 數量,點數換時程等等。 討論 (Discussion):分享兩個故事,第一個是我在水果公司的第二年,當時 Android 團隊剛開始起步,那時團隊成員剛組成,少數人對 Scrum 的認知不是很清楚 (有一半以上的人過去有 Scrum 經驗),所以那時 planning 是先把可工作日乘平均實際工作時數,減去會議時間後再乘上人數得到的總時數,作為 story 是否能排進這個 sprint 的參考,planning meeting 後排進的 task 總時數接近上限。即便如此,回頭看 burn-down chart,task 時數預估其實很少有準過,但消化的 story 數卻有逐漸穩定的趨勢。 第二個是我後來的另一家公司,當時已經跑了四個 sprint 的 Scrum team 突然加了兩個人,然後開發的東西完全換了 (使用的技術和語言都和前一個不同),團隊更動後的第一個 sprint,planning 時使用的方式是用信心指數,也就是 task 切完後,Scrum Master (不是我) 從 priority 高的 story 開始問團隊成員:這個 story 排進去有信心完成嗎?一直到團隊成員沒信心為止,當時 planning 完後總 story 數好像是 26 點,task 總時數是印象中不到 100 小時。某天管理層問 Scrum Master:團隊有六人,兩個禮拜的 sprint 為什麼只有不到 100 小時的 tasks?後來那個 sprint 實際完成的 story 數是 31 點,因為在結束前兩天,又拉了一個 5 點的 story 進來,實際的 task 總 (預估) 時數印象中也才一百出頭。在我離開前,團隊消化的 story 數也趨近一個穩定值。

Scrum Bad Smells 2
Scrum Bad Smells 2
圖片出處:https://workchronicles.com/adding-more-people-to-a-project/

No more calculation

症狀 (Symptom):喜歡用公式換算,像是點數換算時數,時數換算點數,換算可完成的 story 數量,點數換時程等等。

討論 (Discussion):分享兩個故事,第一個是我在水果公司的第二年,當時 Android 團隊剛開始起步,那時團隊成員剛組成,少數人對 Scrum 的認知不是很清楚 (有一半以上的人過去有 Scrum 經驗),所以那時 planning 是先把可工作日乘平均實際工作時數,減去會議時間後再乘上人數得到的總時數,作為 story 是否能排進這個 sprint 的參考,planning meeting 後排進的 task 總時數接近上限。即便如此,回頭看 burn-down chart,task 時數預估其實很少有準過,但消化的 story 數卻有逐漸穩定的趨勢。

第二個是我後來的另一家公司,當時已經跑了四個 sprint 的 Scrum team 突然加了兩個人,然後開發的東西完全換了 (使用的技術和語言都和前一個不同),團隊更動後的第一個 sprint,planning 時使用的方式是用信心指數,也就是 task 切完後,Scrum Master (不是我) 從 priority 高的 story 開始問團隊成員:這個 story 排進去有信心完成嗎?一直到團隊成員沒信心為止,當時 planning 完後總 story 數好像是 26 點,task 總時數是印象中不到 100 小時。某天管理層問 Scrum Master:團隊有六人,兩個禮拜的 sprint 為什麼只有不到 100 小時的 tasks?後來那個 sprint 實際完成的 story 數是 31 點,因為在結束前兩天,又拉了一個 5 點的 story 進來,實際的 task 總 (預估) 時數印象中也才一百出頭。在我離開前,團隊消化的 story 數也趨近一個穩定值。

我不確定看完兩個故事後,大家的感想是什麼?第二個故事裡的團隊很混?事實上,我在上面故事裡有一些沒提到的事情,第一個故事裡,接近 sprint review 的前幾天,團隊的下班時間通常也越晚。第二個故事裡,由於新的工作內容是延續加入的那兩位成員的工作,對使用的技術和語言熟悉的人數比是熟悉 2,對上不熟悉 4,估時的時候,時數常會被熟悉的人牽著鼻子走,但實際執行時,不可能所有的 task 都是熟悉的人施工,因此預估值和實際值的差異時常很大,這也是我當初和 Scrum Master 討論用信心指數決定數量的一個原因。

第二個故事還有後續,當時和 Scrum Master 向公司的顧問提到此事,顧問笑著說,很簡單啊!直接把時數乘上一個倍數,塞滿預估值就好啦!重點是讓管理層相信團隊,如果把預估值塞滿能讓管理層相信團隊有好好地做預估,那就把它塞滿,只要 sprint 結束時能有高品質的產出,而且產能是可被接受的,管理層就不會在意這個預估值是被乘上任意數的結果。我能理解這是權宜之計,但心中總是不那麼踏實,所以,後續的 sprint 我們並沒有真的這樣做,之後 可能因為大家慢慢熟悉技術和語言,點數也成長到四十幾左右,至於預估的總時數呢?這就是有趣的地方了,不知道是生性樂觀還是什麼原因,其實很少會超過 100。

基本上,這陷入了一個換算的盲點:就像是氣象預報,預估終究是預估。如果工作的預估和實際的執行是一致的,就不會有《人月神話》中那一句話:用人月的前提必須是人力與工時可以互換的情況下。我並不是說反正執行結果都不會跟預估的一樣,所以團隊成員在 planning meeting 裡可以亂估,而是要回頭想一下,Scrum 裡 planning meeting 的本質是什麼?是在尋找團隊對 story 及 task 的內容取得共識,以及對這個 sprint 能完成哪些項目進行預報,時數和點數只是用來做預報的參考,這也是為什麼大多數都建議 story 用相對的點數進行預估,而不是用容易被誤解的時數。

回顧:《Scrum Bad Smells 1

回頭檢視待完成草稿時,發現這篇的完成度其實已經可以發布了,想想應該是那時寫完這篇文章時,考慮到文中不少當事人都還是同事,也就沒有發布了,如今文中的當事人都各奔東西,那時的團隊也都不見了,我想應該是可以發布,算是為過去的工作經驗留點紀念吧。

--

--

之前看到同溫層有些人在討論 Deploy on Friday 這件事,本來沒想跟風,偏偏昨晚要下班時,公司設定的 alert 響起,而且還是非常重大的那一種,只好把背包放下,跟其他同事協助將被灌爆的客服。老實說,這不是我們上版引起的,而是我們使用的 Firebase Real-time Database 不知道哪根蔥不對,竟然在周五晚上,餐廳最忙最需要我們系統的時候,搬移我們的資料庫到別台機器上,餐廳非常依賴的資料即時同步功能瞬間就異常大概半小時,於是想寫一下關於 Deploy on Friday 的想法。

當晚客服如預期般接到很多抱怨,我們也發 ticket 詢問 Google,得到的答覆是:原本 host 我們資料庫的那台機器,health check 出現異常,於是啟動了自動搬移機制 (淚)。話說,這算是 Firebase Deploy on Friday 嗎?

首先,我得說,我認為 devOps 是一種不分開發維運、打破籓籬、持續改善與盡早交付的精神。所以我們做很多自動化的測試 (不管是單元測試、整合測試、壓力測試都做)、自動化的布署、任何能讓上線比較沒壓力及降低風險的事。終極目標就是不管是周五也好,周末也罷,只要想 Deploy,隨時都能 Deploy。

但什麼時候上線,還是回歸到風險控管吧。無論花了多少資源進行測試,都無法保證一個新版本是沒有 bug 的,所以新版本上線後還是有一定的機率會出錯,對!不管是一個星期的哪一天,機率都是一樣的,所以哪一天上版都可能會出錯,但出錯造成的損失就不見得一樣。

不同的產業,不同的服務類型,就有不同的損失分布,像是 Facebook,壞了對我來說不痛不癢,不用它幾小時不是什麼大問題,這類對多數人來說不是 mission critical 的服務,哪天上新版損失是差不多的。但是像我一開始提到的,周五晚上以及周末,是餐廳業績最好也是最忙碌的時間,我們在周五上新版若出錯,對餐廳所造成的營業損失肯定是高於平日的,這時候還會選擇周五上新版?

當然,若已知上新版本的獲利遠大於損失,那就上啊!這還有什麼好說的。(笑)

如果說機率是一樣的,且已知某天上版造成損失是高的,是否有方式降低損失呢?這命題遠比為何不能在周五上版來的正向許多。

例如,我們的退版速度能多快?需要很複雜的步驟才能退版嗎?畢竟不是所有的情況都能夠快速地退版,像是 iOS app 或牽扯到資料庫 schema 變動都可能無法很快速地退版。iOS app 從送審到等待通過,這段時間的操控權不在開發者手上,甚至遇到聖誕長假,Apple 是不審理 app 新版本上架的 (我沒在聖誕長假期間送過緊急審查,不確定審不審),這都會影響是否要上新版本的決策。如果退版只是一個按鈕,或是能在幾分鐘內就完成,上新版或許就不是太大的問題,就看這損失我們是否願意承擔。

或是上新版後,我們可以用 feature toggle 控制損害範圍,像是新功能只有少數的使用者才能夠使用,當新功能出錯時,也只有這些使用者會受影響,或是反過來用,當新功能出錯時,不用退版就能將這功能關閉,讓使用者回到舊版本繼續使用服務。例如 Apple 就階段性發布自動更新的機制,以 1%、2%、 5%、10%、20%、50%、100% 的比例推送自動更新,還能夠暫停發布。也就是說若 API 上版也能夠用同的方式管控,就能控制損害的程度。

又或者是,調整系統架構,能讓上新版的影響範圍降到最小,我並不是在推崇 micro-service 架構或是什麼廠商的 serverless 方案,光是最基本的,系統架構模組化,讓修改的影響侷限在一個模組內,這樣就能夠大大降低上新版的風險,如果系統架構沒有好好的模組化,改一個東西或加一個新功能,動輒改上數十個檔案,我相信上版時心裡還是會怕怕的。

抱有持續不斷地改進的精神,努力降低上版的風險,最後,哪一天上版就僅僅是風險控管的問題了。

這個議題的另一個面向,很多人直指不想周末加班或 on-call,所以這題目可以更 general 一點,該不該在假日前上版,像是農曆新年連假、中秋連假、國慶連假,以我們的產品特性,我們都是較保守不上版,不是因為沒信心,而是找不到理由要在客戶最忙的時刻增加風險 (相較已穩定運行的舊版本)。

我曾在某年的最後一天,雖然那天放假,我仍跟老闆到某家在信義區的知名拉麵店,不是去吃拉麵,而是去查找為什麼平安夜那晚候位出單機的出單速度異常緩慢,說真的,這功能上線前我們也是做了不少的測試,他們剛開始用時,也曾在那邊站了數小時觀察使用情況,認為不會有問題,偏偏平安夜那晚有時候要 10 秒才出一張單。最後我們請店家不要使用 4G 分享器 (我相信很多人都有過跨年時手機訊號滿格卻沒有網路的情況),改使用獨立的 WIFI 就沒問題了。

我想說的是,當線上的系統出現問題,多數工程師還是願意犧牲自己的假日解決問題,但不代表當有不用加班的選擇時 (舊版本已穩定運行一段時間),卻要刻意拿石頭砸自己的腳 (放假前上新版本)。畢竟在上班日上新版,若出現問題,可以在上班日處理。

雖然有人提到,公司要有好的 on-call 機制,讓工程師更願意 on-call,像是提供加班費、補假、獎金等等。當我們在譴責公車公司讓司機疲勞駕駛時,卻又同時用這些機制鼓勵工程師加班?即便有這些獎勵,每個人的價值觀不同,也不是每個工程師都願意這樣砸自己的腳,我相信多數人不希望在帶小朋友去公園玩時,看到手機簡訊後跟小朋友說:

不好意思,爸爸昨天手賤,硬是要上新版本,但現在出了點問題,所以爸爸現在不能陪妳,得去公司處理點事情。

至於這樣的人多不多?這問題其實很簡單,在面試的時候只要問,您是否願意配合 on-call,即便有這麼多獎勵機制,我保證還是能夠刷掉一大票的人,即便是能力好的人也是有不願意配合的。這是價值觀選擇的問題,只靠獎勵機制說服不同世界的人是有難度的。

我倒覺得,應該要做的是平常多進行教育訓練,畢竟當系統越來越大,不是每個人都會參與所有的功能開發,當 on-call 時遇到不熟悉的系統功能,自然壓力會很大,透過這種方式,盡可能到減輕 on-call 時要面臨的壓力,會比較正向一點,像最近我們就辦了很多次 workshop,講解過去可能都是由資深人員處理的線上問題,讓其他人有機會可以處理。

最後總結,針對這議題,從 devOps 的角度看,團隊應抱有持續不斷地改進的精神,努力降低上版的風險,最後,哪一天上版就僅僅是風險控管的問題了。風險控管除了考量到損失,當然還要考慮到團隊要怎麼 on-call,on-call 的資源夠不夠應付上版後的突發狀況,才能做出適當的決策。

上面說這麼多,那我們有針對 Firebase Real-time Database 會無預警搬移機器這件事做什麼努力嗎?有的,像是之前用 shard,分散資料,讓單一 shard 影響的餐廳數減少。最近則是在進行架構調整,但由於 root cause 是非常底層的資料庫以及整個資料即時同步的機制,所以牽動到的範圍就非常大。不過搭配 feature toggle,我們架構調整的程式碼不是在一個獨立的分支上,而是一直持續不斷地回到主線上,能持續上線其它新功能而不受影響。目前正在 beta 環境上進行大規模的測試。改天有機會再來分享。

雖然掛在閒談軟體架構系列,但整篇文章似乎只有模組化、micro-service 或是 feature toggle 幾個關鍵字跟架構比較有直接關係 (笑),其實這是團隊文化的建立問題,也會影響到系統架構的設計。

系列索引
上一篇:《閒談軟體架構:Switch 壞味道
下一篇:《閒談軟體架構:Singleton

--

--