基於 Feature Flag 的下一代開發模式

語言: CN / TW / HK

面向快速迭代,如何降低上線風險?位元組跳動 DataTester 團隊找到風險與迭代的平衡點——漸進式釋出。

漸進式釋出(Progressive Delivery)被認為是持續釋出(Continous Delivery)的下一代形態,其專注於增強釋出過程控制與降低釋出風險,最終提高整體收益。國際科技巨頭比如 Amazon、Google 和 Netflix 等公司每天通過漸進式釋出的方式將數千次的功能更新、bug 修復等更新到使用者環境。

快速迭代的同時,避免不了引入一些預期之外的 bug。因此需要如何採用合適的工具,在風險與收益之間找到一個很好的平衡點就顯得尤為重要。目前持續釋出(CD)能夠通過一些使用者資料、系統監控或者一些核心指標對部署的功能進行監控,當發現問題及時回滾,以此形成一個持續迭代閉環。但是當用戶體量非常大的時候,一個小的問題可能會造成難以衡量的損失,這是不可接受的。

為了找到風險與迭代的平衡點,漸進式釋出的方式漸漸被提出並且深受重視。

什麼是漸進式釋出

漸進式釋出有兩個特點:釋出進度控制和釋出階段授權。

其中釋出進度控制即按一定的節奏將新的軟體或者功能向用戶推送,釋出節奏可以是連續的也可以是分步驟的,以此控制每次生效的範圍。這種做法建立在持續交付的核心原則之上,即將“程式碼部署”與“功能釋出”分開。

釋出階段授權是指在不同的階段將功能的操作許可權授權給不同的團隊,比如將功能的所有權慢慢從工程轉移到產品,然後從產品管理轉移到營銷等等。

釋出進度控制和釋出階段授權並用,降低了持續交付相關的風險,並賦予團隊在整個釋出週期中更多的控制權。

持續釋出與漸進式釋出區別

持續整合與持續釋出(CI/CD)中強調主幹分支的程式碼需要時刻保持在可部署的狀態,這需要不斷地將 feature 開發分支與主幹分支進行合併,而不是等待一週甚至幾周的時間,待所有功能開發完並通過完整的測試再合併到主幹分支。CI/CD 的目的就是為了加快軟體的開發與部署速度與效率,將新的功能儘快部署上線,同時儘可能降低風險。

雖然 CI/CD 能夠加速軟體與功能的交付速度,但是與之而來的風險並沒有很好消除。當所有功能一次上線到生產環境後,如果包含比較嚴重的 bug 但不能及時發現,結果將很難預料。雖然 CI/CD 模型中的金絲雀釋出(canary release)能夠控制 bug 影響的範圍,但是需要依賴比較複雜的控制系統。因此目前大部分場景下的 CI/CD 系統並不是嚴格意義上的持續整合與持續交付,大部分情況還是基於 feature 分支進行開發,然後在合適的時機合併到主幹分支一併進行上線。

而漸進式釋出的方式將新的功能隱藏在一個 feature flag 中,並可以通過視覺化介面對釋出的過程進行靈活控制,這是漸進式釋出與目前 CI/CD 形態的一個比較關鍵的區別,其示意圖。此外還有一鍵關閉、緊急生效引數、流量控制與監控等功能,當出現問題時不需要重新部署程式碼,通過按鍵即可進行功能的回滾,進而儘可能減少故障時的影響範圍。可以說漸進式釋出就是為解決釋出問題、提高發布穩定性而生的釋出理念。

那麼漸進式釋出有那麼多的優點,想要獨立開發一套控制系統又非常複雜,有沒有簡單易用的平臺可以使用呢?答案是肯定的,火山引擎 A/B 測試中 FeatureFlag 智慧釋出專注於打磨釋出平臺,並實現與 A/B 測試的全方位聯動,將是一個不錯的選擇。

FeatureFlag 智慧釋出平臺是什麼

Feature Flag 即 Feature Toggle,顧名思義其本質是一個隱藏在業務程式碼裡面的一個控制邏輯。雖然看似簡單的 if else 邏輯,但在釋出領域有著非常強大的功能,可以實現生產環境中功能的動態控制而不需要要重新部署程式碼;此外還能夠實現對生效流量、目標受眾的靈活控制。

火山引擎A/B測試FeatureFlag功能基於先進的智慧釋出引擎和一站式配置託管平臺,滿足業務灰度發版、A/B 測試、定向差異化釋出等不同應用場景。幫助開發、產品、運維人員在低風險環境下迭代新 Feature、修復 bug,實現精益敏捷開發。其核心目標在於保障應用迭代質量、助力精益開發效率、支援精細化業務場景與產品矩陣賦能。

如何基於 FeatureFlag 實現漸進式釋出

一個好的平臺想要做到易用一定要在功能複雜性與互動簡潔性之間尋找平衡點。因此為了降低使用門檻,目前 Feature Flag 功能的配置只需要四步即可完成所需引數的配置,下面將對配置過程簡要介紹。

01 - 基本資訊配置

基本資訊中的必須引數有 Feature 名稱、Feature 對應的 key(也即某個功能對應的開關)和端型別。其中服務端與客戶端只有在整合的時候稍有差別,但是在平臺上使用的時候操作一致。所以只需要簡單填寫幾個必須引數,第一步就完成了。

何為變體呢?其實可以簡單理解 Feature Key 用於標識功能,而變體的值即為 Feature Key 對應的值,對應到程式碼裡面這個值就是控制 if else 邏輯的資料。目前 Feature Flag 支援四種類型的引數配置,可以按需使用。

釋出受眾顧名思義用來控制當前配置的生效範圍,其分為三個部****分。受眾白名單即為優先順序最高的受眾條件,如果為某個使用者開通了白名單,那麼該使用者會優先生效變體對應的值。自定義受眾規則則可以靈活根據使用者屬性進行目標受眾的圈選,這些引數和使用者上報的屬性相關,比如截圖中即為渠道為 app store 且瀏覽器為 chrome 的使用者會生效變體 2。均不符合以上條件的使用者則會生效預設最終規則變體 1。

目前如果開通了 APM Insight 功能,那麼是可以在監控指標這裡選擇一些預定義的效能指標作為監控,可以根據釋出狀態實時監控當前線上使用者的情況,出現問題可以及時回滾。比如下圖即為 JS 錯誤率的監控和聚合後的報警事件結果。

02 - 釋出進度控制

為了實現漸進式釋出中對釋出進度的靈活控制,目前支援了手動釋出、定時釋出、自動下線、一鍵關閉、定向釋出與隨機發布等功能。現分別介紹如下。

手動增量釋出

使用者可以手動對當前的釋出流量進行調節,進而實現對釋出範圍的控制。

適用場景

  • 新功能上線,需要謹慎控制生效範圍與效果
  • 功能的釋出節奏無法通過時間控制

定時自動釋出

定時自動釋出中可以提前按時間線設定流量的生效情況,到時間後將會自動生效對特定流量範圍的使用者生效。

適用場景

  • 節日活動,需要在特定時間生效相關配置

一鍵關閉

Feature Flag 能夠幫助使用者在生產環境測試新的 feature 效果,並可以通過開關快速的控制新 feature 的狀態,以最大化的降低因新 feature 出現問題對線上環境的影響。傳統情況下,上線新功能後發現問題的修改往往需要對程式碼的修改與服務的重新部署,進而會導致服務在一段時間內不可用,而這個過程往往比開關的控制更為複雜。該技術的背後是使用不同的邏輯分支,當 Feature Flag 開啟的時候開啟某些功能,反之關閉某些功能。

例如某個介面對一個看板進行了優化,那麼可以通過配置 feature key 的方式,讓一部分使用者先體驗新的看板功能,另一部分使用者維持原樣,這樣一來可以根據線上效果判斷這個功能對系統穩定性帶來影響,也可以避免新看板存在的 bug 影響到整體的使用者。在程式碼中你可能需要提前使用如下的程式碼:

if (isFeatureEnabled(‘new_dashboard’)) { // true or false ​ showNewDashboard(); ​ } else { ​ showExistingDashboard(); ​ }

定向釋出

定向釋出即只對指定使用者生效特定新功能。Feature flag 可以通過使用者分群或自動以目標受眾的方式,控制新功能只對小範圍使用者生效。

例如,新上線的看板只對開通渠道為 app store 的使用者生效。其程式碼如下:

if (isFeatureEnabled(‘channel’, ’app store‘)) { // true or false showNewDashboard();
} else { showExistingDashboard();
}


 適用場景

  • 比如某些使用者已經是老粉了,而且傾向於儘早體驗到產品的新功能,那麼可以據此建立內測使用者分群,新功能優先向這些使用者推送。內測使用者往往能夠儘早為新功能提供反饋,進而及時做出功能調整。
  • 國際化公司,在不同國家上線功能,可以通過國家圈選不同使用者,進而為不同區域定製功能開發。
  • 新的功能可以使用免費使用者進行測試,檢視功能的效果。

隨機發布

隨機發布即從線上所有使用者抽取一部分流量做驗證,如下圖所示。

適用場景

  • 新功能逐步上線,較指定日期全量上線,大大減小風險,即使出問題也只會影響一小部分使用者,能夠及時回滾。
  • 風險較大的變更上線(例如基礎設施遷移,資料遷移,大型重構或基礎架構更改),基本不會對您的產品或業務產生負面影響。
  • 提早暴露效能等問題,通過一部分流量的資料可以預測未來服務效能的變化,而不至於新功能的上線導致服務不可用。

03 - 釋出階段授權

釋出階段性授權是漸進式釋出的另一個特點,那麼 FeatureFlag 中同樣也是支援的。具體的釋出階段授權主要包括兩部分:許可權管理和工作流程管理。

許可權管理

結合賬號體系,可以對每個 feature 按角色和使用者設定許可權。如果一個 feature 還在測試早期那麼可以只為角色為研發的使用者開通許可權,以此類推。慢慢的將許可權的控制移交給售前或者運營,實現功能上線與生效的分離。

工作流程管理

工作流程管理可以對釋出過程進行控制,在不同的釋出階段可以引入不同的角色或者使用者進行稽核,靈活調整每個釋出階段的授權範圍,確保釋出過程的可控性。

FeatureFlag 智慧釋出有哪些應用場景

FeatureFlag 的應用場景非常多,基於其提供的漸進式釋出能力,可以加速產品迭代過程,提升服務穩定性。下面從幾個方面介紹下常見的應用場景。

01 - 新功能灰度釋出

新功能發版可逐步灰度擴量,先讓小部分使用者體驗新功能,觀察使用者反饋和資料表現,再初步擴量,潛藏問題及時發現快速止損,如下圖所示。

  • Step1 白名單測試+內測+眾測
    新功能上線前,先用白名單測試,並讓內部使用者和外部眾測使用者參與驗證執行一段時間保證穩定性。
  • Step2 釋出稽核內測通過後,邀請組內其他人蔘與 Review,通過後再進行後續的灰度。
  • Step3 流量灰度+增量釋出
    優先選擇 1%小流量,沒問題逐步調整流量比例,灰度放量。在小流量過程發現了問題,我們及時回滾了配置,讓舊版本配置生效。修復後再逐步放量新版本。  

02 - FeatureFlag 與 A/B 測試打通

與 A/B 測試打通是火山引擎 FeatureFlag 功能的一大特色,兩者的珠聯璧合將會大大加快產品的迭代速度與效率。具體場景可分為以下三個部分:

  • A/B 實驗產生優勝版本後,可直接將實驗固化為 feature,實現 A/B 實驗的快速全量,並可採用灰度釋出更加穩健全量。
  • 在 FeatureFlag 智慧釋出建立 feature 後,可直接由 feature 開啟 A/B 實驗,快捷實現實驗的開啟和後續的管理。
  • A/B 實驗的引數可固化為 feature,放在 FeatureFlag 智慧釋出統一管理,產品可全域性檢視 feature 版本與實驗的關係。

那麼 A/B 測試與 FeatureFlag 兩者間可以相互轉化,他們之間的關係是怎麼樣的以及使用場景應該如何抉擇?

A/B 測試是效果測試(一般用來驗證某個想法是否符合預期),同一時間有多個版本功能對外提供服務,這些功能都是經過足夠測試,達到了上線標準的服務,有差異但是沒有新舊之分。它關注的是不同版本功能的實際效果,比如說轉化率、留存等。其目的是為了驗證產品的迭代方向是否正確。

Feature Flag 強調的是釋出策略,目標是確保新上線的系統穩定,關注的是新系統的 BUG、效能隱患及穩定性,強調在釋出過程中能夠較早發現問題的存在。

Feature Flag 與 A/B 測試的抉擇流程可以參考下圖。

03 - 異常監控智慧告警

目前 FeatureFlag 智慧釋出已經和 APM 應用效能監控打通,可實現從應用—>Feature—>Flag 級別的監控 。當某個監聽的技術指標出現異常時自動觸發報警,快速發現線上異常問題。後續對服務端技術指標的支援。

  • 指標靈活組合,讓監控更加便捷。
  • 報警事件聚合,讓監控更加完善
  • 有效性驗證+ACK,讓監控更有效。 

04 - 千人千面-人群差異化釋出

基於 FeatureFlag 中靈活的自定義目標受眾條件,可以實現不同使用者下發不同的配置引數,真正實現千人千面,靈活釋出。

  1. 可以根據不同人群特點展示功能,比如安卓使用者推薦 QQ 登入,IOS 使用者推薦微信登入,提升不同人群的個性化體驗。
  2. 運營活動時,可針對不同地域、人群採用差異化的運營策略,實現細分人群的精細化運營。
  3. 自定義目標受眾引數,滿足業務定製化的定向釋出需求。

05 - 增強持續整合與持續部署能力

CI/CD 使得開發者可以快速開發、迭代與釋出新功能。持續部署(符合企業軟體實踐,它是完善持續整合原則的自然演化。但持續整合與部署案例卻非常罕見,其中原因可能是需要複雜的管理以及擔心部署失敗而影響系統的可用性。

目前在開發過程中,開發者會從 develop 分支 checkout 新的分支出去開發自己的新功能,在充分測試完成後再合併到主幹分支,這樣主幹分支能夠保證在任意時刻都是可以上線的狀態。但是這種開發方式存在一些問題,比如分支分出去時間越長往往程式碼合併難度越大。一旦程式碼庫中存在了分支,也就不再是真正的持續集成了。當然你可以給每個分支建立一個對應的 CI,但它只能測試當前分支的正確性。如果在一個分支中修改了函式功能,但是在另一個分支還是按照原來的假設在使用,在合併的時候會引入 bug,需要大量的時間來修復這些 bug。

而基於 Feature Flag 的 CI 過程則如下圖所示。開發完成的程式碼可以在任意時刻合到主幹分支中,並通過 Feature Flag 開關控制未開發完成的功能對使用者不可見;新的特性可以提前上線,產品或者運營等角色可通過開關控制何時與什麼範圍生效新的 Feature;對線上問題的修復,可以通過控制釋出範圍,使用線上流量進行驗證。

  1. 進一步加快 CI/CD 程序,主幹分支隨時可以部署,提高迭代效率。
  2. 功能上線與程式碼部署的分離,通過 flag 將新功能隱藏,一方面方便線上小流量測試,另一方面產品或者運營可以按需開啟功能,不需要再問研發要排期,提高協作效率。 

總結

持續釋出在現代軟體公司的發展過程中發揮了比較重要的作用,但是持續釋出時不增加必要的控制是非常危險的。漸進式釋出方式在整個釋出過程中加入了足夠的控制,並且融合了釋出階段授權,可以大大降低持續部署時可能導致的問題。

FeatureFlag 智慧釋出能夠更加方便幫助使用者實現漸進式釋出,並減少產品迭代過程中引入的問題和上線風險,最終在降低風險的前提下提高迭代速度。快速迭代、保證安全和實時控制,這就是火山引擎 A/B 測試的 FeatureFlag 智慧釋出功能。

**功能體驗傳送門:[火山引擎FeatureFlag]

**瞭解更多請戳:[火山引擎Feature智慧釋出幫助中心]

火山引擎 A/B 測試

A/B 測試,擺脫猜測,用科學的實驗衡量決策收益,打造更好的產品,讓業務的每一步都通往增長。

當前,火山引擎首度釋出增長助推「火種計劃」,火山引擎 A/B 測試作為「火種計劃」產品之一,將為您免費提 2 億事件量和 5 萬 MAU,以及高達 12 個月的使用權。[體驗傳送門]

歡迎關注**“位元組跳動資料平臺”**同名公眾號