返回開發人員最新消息

揭露未知的未知項目

2023年5月16日發佈者:Andrew Reedy

Meta 擁有一個數十億用戶每天使用的產品生態系統,無論是進行社交聯繫或商家互動。這些數十億用戶同時要求我們持續以更快的速度在我們的產品中提供新功能和改進。由於用戶基礎龐大,我們每天皆進行數千次程式碼變更以滿足用戶的期望。

持續發佈如此大量的產品改進可能造成應用程式健康狀態退化,進而導致用戶體驗下降。在 Meta,我們具有複雜的預防工具層級,可防止發佈錯誤的產品變更。這些預防工具會在應用程式發佈之前,監控各種產品訊號並偵測退化狀態。這些訊號屬於三個領域:效能(performance)、可靠性(reliability)(功能和系統)和效率(efficiency),統稱為產品的「PRE」。當開發人員撰寫程式碼時,系統即透過各種可檢視性和收集的分析追蹤開始進行預防作業。此外,可檢視性和監控工具會從預先生產環境中的產品內部使用方式收集資料。手動和自動品質保證工具都會在這些預先生產環境中測試產品。

雖然這些機制用於評估程式碼變更在投入生產之前的品質(因而避免對用戶造成影響),但影響用戶的變更可能會進入生產環境,因此需要重新設計並再次投入。為了降低問題影響大量人口的可能性,我們使用各種機制來逐步公開發佈變更。

當功能偏離用戶期望時,我們將其定義為退化。我們使用「訊號」一詞來表示用戶讓我們知道某些功能不符合他們的期望。我們透過資料洞察報告和檢測的程式碼,儘快有系統地收集退化訊號,然後部署修復項目來減少對用戶的影響。在無法從工具中取得強烈訊號的情況下,我們依賴用戶報告作為已發生退化的訊號。這些報告經由各種機制提供,例如:用戶在問題發生時,搖晃手機回報他們所在的應用程式問題內容。

為了確保我們儘快滿足顧客的需求(有時在當天內),Meta 在多個可靠性計畫和系統上投入大量資金,以能夠實現大規模的有效回應能力。

訊號可以來自我們的公開用戶(個人、公司、社團等)或內部用戶。我們會仔細檢查來自內部用戶的訊號,以協助防止不受歡迎的變更投入生產環境。請注意,訊號是彙總的,例如:訊號包括每百萬用戶的故障數。訊號也可以來自自動化測試工具和案例、開發工具(我們警告開發人員可能導致執行階段問題的變更)、系統紀錄及其他許多來源。我們同時具備利用這些訊號的工具,以便快速查明原因並進行適當修復。

一旦確定退化狀態,我們就會繼續快速找到相關工程師套用修復並進行發佈。我們會依據退化的複雜性,採用多種方法來確定合適的工程師,包括利用 Meta 在機器學習方面的敏銳度。由於機器學習的運作方式,這是一個持續的程序,因此我們發佈新功能並重新訓練我們的模型以因應不斷的變化。

上述最後的結果為:我們從檢測退化、降低影響,到加以預防並可持續地進行監控。在此程序中,我們充分提升了回應能力、投資報酬(率)和效率。

在下一節中,我們將更詳細地討論我們如何確定退化已經發生,並在知道時如何回應。

將未知項目轉換為已知項目並加以量化

當我們談論未知項目時,指的是用戶或系統正在經歷的故障。首先,我們可能會從許多不同的來源瞭解可能的故障。

  • 綜合測試我們的應用程式和這些應用程式內特定產品的正常運作。
  • 測試以找出故障的內部用戶,可包括我們專屬的測試團隊,或 Meta 內更廣泛的用戶群。
  • 使用我們應用程式中的問題回報對話方塊遇到問題的外部用戶。

這些故障在實際標記為用戶遇到的事件之前屬於未知項目。當此類故障報告的數量達到某個臨界值時,我們會將其確判為代表真的退化事件:程式碼變更已經產生新的故障,我們必須迅速降低其造成的影響。有兩種主要類型的報告:

  • 「已知的未知項目」- 當檢測程式碼偵測並回報退化且我們有許多工具可協助產生此訊號時
  • 「未知的未知項目」- 當內部未攔截到退化且我們依賴用戶實際回報退化時

此外,退化可分為幾個類別,例如:是否表示程式碼錯誤、更像垃圾訊息或其他內容政策違規。我們的重點在第一個領域,希望解決與程式碼相關的用戶體驗問題。針對回報數千個問題的用戶,您要如何處理?

產生訊號和洞察報告

為了管理大量報告,我們會產生特定訊號來為我們標記問題。第一種類型的訊號是經過適當調整的臨界值,通知我們確實發生事件或退化。請注意,根據退化的類型,可能會發生多個事件。例如,由於通用程式碼基底,退化可能會影響多個產品。我們會尋找這些共通性,將其作為單一事件來解決,以最佳方式調整資源。下圖是我們以視覺化方式呈現偏離趨勢線的範例,指示發生退化。

我們接著會收集其他訊號,其中一些訊號指示我們可能面臨的退化類型。這些訊號有助於深入瞭解與退化相關的癥狀,並由針對特定 Meta 產品最佳化的機器學習演算法產生。演算法會分析用戶報告以找出導致退化的原因,進而確定哪個工程團隊可透過部署程式碼修復或其他措施來有效解決問題。

許多其他訊號也是根據已收集的紀錄資料所產生。這些診斷紀錄可以是用戶端或伺服器端紀錄,是在用戶同意的情況下所收集,以協助確定原因。應用程式包含適當的同意流程,確定是否可根據用戶的權限收集此類資料。我們同時考慮這些資料的使用壽命,以符合適用的法規。

訊號組合使我們能夠專注於退化並將其指派給正確的產品團隊,以快速降低問題造成的影響並將用戶體驗回復到他們期望的狀態。

洞察報告也來自彙總的調查結果。我們會查看資料以找到共同的根本原因,並確定是否需要進行變更以防止退化再次發生。這麼做是採用可靠方法解決用戶體驗問題的一個關鍵要點,因其可協助我們隨時間變化有效減少退化的發生。

我們的行動應用程式不僅包括允許用戶回報問題的導覽路徑,同時提供透過搖晃裝置來指示問題的功能。如此一來,我們就可以收集內容的遙測。經由來自應用程式的黑箱訊號可讓遙測更加豐富。黑箱就像飛行記錄器,會自動擷取特定紀錄(經用戶同意),內容為應用程式在經回報故障的當下出了什麼差錯,以便我們能夠有效地診斷問題。

所有這些遙測都拼接到一組時間表檢視中,以協助工程團隊確定導致問題的原因。由於我們應用程式的快速發佈節奏以及伺服器端應用程式元件的變更,如果沒有此功能,將很難查明問題。隨時間變化進行此遙測有助於我們偵測退化中的模式,可防止這些模式在將來出現。

調整成較小的產品介面

我們已提升在訊號中產生更高精確度的能力,因此能夠攻擊更多的退化介面,其中部分在以前是無法偵測到的。介面表示產品內的特定提供項目,例如:動態消息或 Reels。這是一項挑戰,因為產品不僅具有許多細微功能,而且會定期導入新功能。因此,退化介面不僅很大,而且還會隨時間變化而增長。因此,我們的防禦和進攻策略必須不斷調適。

若要進行調整,需要滿足幾個條件:

  1. 我們必須對現有產品介面進行精確涵蓋和適當分類
  2. 我們必須減少現有產品的退化介面(閱讀:預防)
  3. 我們必須將演算法的範圍擴展至新產品介面

若未滿足上述條件,我們就可能擁有一個因規模、複雜性和不準確性而無法管理的臃腫系統。因此,我們努力保持這種平衡,同時有效地執行我們的日常運作。

擺脫故障

由於我們持續減少退化介面(不放鬆警戒),因而更加專注於其他重要領域:預防和可用性。

預防關係到以下內容:

  1. 我們如何從先前的退化中學習?
  2. 我們實施哪些防禦措施才能使這些退化不再發生?
  3. 我們如何確保退化介面會隨時間變化不斷減少?

如前所述,我們彙總先前的退化資料以從中學習。這些學習可以轉化為:

  1. 在仍處於預先生產環境中時,於程式碼內放置標記供將來提醒之用,以便我們可以阻擋不必要的變更進入生產環境
  2. 增加各個層級的測試涵蓋率以偵測此類退化
  3. 對產品本身進行變更來解決這些問題

預防有助於我們將開發生命週期中剩餘的退化持續轉移,進而不斷降低成本。這是透過在開發程序早期(從程式碼撰寫和預先生產發佈週期開始)獲得足夠豐富的訊號而得以完成。這不僅能改進用戶體驗,還可降低開發成本,有助於我們將資源轉移至新產品開發。

改進能夠更有效處理退化的能力可讓我們更專注於用戶混淆或可用性問題。這些是更高價值的問題,因為我們會專注於改進產品而不是將其修復。隨著時間變化,可用性問題與退化的比例應該會增加,而可用性問題和退化的總數則應該會減少。

最後,這將使用戶體驗的功能性和可用性方面獲得持續的改進。

本文是與 Meta 的技術專案經理 Bijan Marjan 合作撰寫。