文章目錄
- 背景
- Flagsmith 和 Unleash
- 什么是unleash
- 架構
- Unleash Edge
- 安裝和使用
- Unleash SDKs
- 開放API Tokens訪問
- **`Server-side SDK (CLIENT)`**
- **查詢所有 Feature Toggles**
- **查詢特定 Toggle**
- API token types
- Client tokens
- Frontend tokens
- Personal access tokens
- Service account tokens
- go sdk demo
背景
功能管理是持續發布/持續部署 ( CI/CD ) 流程的重要組成部分,它允許開發人員與一小部分用戶逐步測試新功能、打開或關閉功能以及進行 A/B 測試,以深入了解什么是最有效的,而無需發布一個全新的版本。
對項目內的功能啟用進行動態控制, Feature Toggle,
Feature Toggle,顧名思義就是表示 Feature 的開關,通常可以使用 Feature Toggle 來管理不同功能開關,并且可以根據不同的參數對開關進行動態配置。在項目中引入 Feature Toggle 可以更好的對于功能進行灰度發布和定向測試。
Netflix的開源項目Unleash正是這樣一款工具,它提供了一種動態管理應用程序功能開關的方式,幫助企業更有效地進行灰度發布、A/B測試和其他迭代策略。
開源方案 Unleash。Unleash 是一個開源的 Feature Toggle 服務。
Flagsmith 和 Unleash
Flagsmith 視頻介紹:https://www.reddit.com/r/selfhosted/comments/o5hyug/self_hosted_feature_flag_and_remote_config/?tl=zh-hans
場景 | Flagsmith | Unleash |
---|---|---|
快速集成 | 適合需要 SaaS 或快速啟動的項目 | 適合愿意自托管且需要靈活策略的團隊 |
復雜策略 | 支持 A/B 測試和用戶細分 | 支持更復雜的自定義策略(如漸進式發布) |
邊緣計算 | 本地評估減少延遲 | 依賴中心化服務器 |
動態配置 | 支持遠程配置參數 | 僅支持功能開關 |
特性 | Flagsmith | Unleash |
---|---|---|
開源版本 | 完全開源(MIT 許可證) | 完全開源(Apache 2.0) |
企業版 | 提供付費 SaaS 和企業支持 | 無官方 SaaS,但有商業支持選項 |
社區支持 | 活躍的社區和文檔 | 社區活躍,文檔詳細 |
- 選擇 Flagsmith 如果:
- 需要 SaaS 解決方案或快速啟動。
- 需要內置 A/B 測試或動態配置。
- 優先考慮本地評估(如移動端或邊緣場景)。
- 選擇 Unleash 如果:
- 需要完全自托管和靈活的自定義策略。
- 專注于功能開關和漸進式發布。
- 愿意維護自己的基礎設施。
什么是unleash
官方文檔:https://docs.getunleash.io/
官方倉庫:https://github.com/Unleash
Unleash 是一個開源的功能標志(feature flags) 和管理平臺,允許您在不中斷服務的情況下安全地發布和測試新功能。它提供了一個集中式界面,用于管理和控制哪些用戶可以看到哪些功能,以及如何啟用這些功能。
Unleash 提供了一個簡單的管理平臺,我們可以在這個管理后臺上進行 Feature Toggle 的管理和查看。
通過使用Unleash,您的團隊可以在不依賴分支的情況下并行開發多個特性,實現敏捷開發的最佳實踐。這個平臺支持15個官方SDK和多個社區貢獻的SDK,可與任何語言和框架無縫集成。
總而言之,Unleash 幫助團隊安全地發布和管理新功能,提升了開發效率,并降低了發布風險。
Unleash廣泛應用于以下場景:
- 快速迭代:啟用或禁用代碼以控制新特性的發布速度。
- 灰度發布:逐步向一小部分用戶推出新特性,收集反饋并調整。
- A/B測試:對不同用戶群體實施不同的功能版本,比較效果。
- 風險控制:若發現新特性有問題,可以通過切換關閉旗標來迅速回滾。
架構
Unleash Edge
官方文檔:https://docs.getunleash.io/reference/unleash-edge
https://github.com/Unleash/unleash-edge/blob/main/docs/concepts.md
Unleash Proxy is in maintenance mode. Use Unleash Edge instead.Unleash Proxy 處于維護模式。請改用 Unleash Edge。
Unleash Edge 是 Unleash Proxy 的繼任者。如需有關從 Proxy 遷移到 Edge 的幫助,請參閱遷移指南。
Unleash Edge 是 Unleash API 和 SDK 之間快速輕量級的代理層。它充當 Unleash 實例的只讀副本,旨在幫助您擴展 Unleash。它允許您支持數千個連接的 SDK,而無需增加對 Unleash 實例發出的請求數量。
- 使用獨立于 Unleash 服務器的 Unleash Edge 進行擴展,以支持任意數量的前端客戶端,而不會使您的 Unleash 實例過載.
- 前端 SDK 通過 Unleash Edge 連接,以確保隱私、可擴展性和安全性。
Edge 目前支持 2 種不同的模式:
- Edge - 連接到上游節點(Unleash 實例或另一個 Edge)。 支持動態令牌、指標和 其他高級功能;
- 離線 - 沒有連接到上游節點。完全控制數據和令牌;
Unleash客戶端SDK,可以與Unleash前端API或Unleash代理或Unleash Edge一起使用。這使得任何Flutter應用程序使用Unleash變得非常簡單。
主要特性:
- 性能: Edge 使用內存緩存,可以在靠近最終用戶的位置運行。單個實例每秒可以處理成千上萬個請求。
- 彈性:Edge 旨在在重啟后繼續運行,即使您與 Unleash 服務器斷開連接也能保持功能。
- 安全性: Edge 支持前端應用程序,而不會將敏感數據暴露給最終用戶或 Unleash。
您可以在兩種不同的模式下運行 Edge:edge 或 offline。要了解有關不同模式和其他 Edge 概念的信息,請訪問 Concepts。
安裝和使用
參照官方文檔 進行安裝。
要在本地設置 Unleash,您需要在您的機器上安裝 git 和 docker。
執行以下命令:
git clone git@github.com:Unleash/unleash.gitcd unleash
docker compose -f docker-compose-enterprise.yml up -d
這會拉取 unleashorg/unleash-enterprise
Docker 鏡像,并使用 Docker Compose 文件來配置 Unleash 服務器及其數據庫。
然后將您的瀏覽器指向 localhost:4242 并使用以下信息登錄:
username: admin
password: unleash4all
Unleash SDKs
官方github:https://github.com/Unleash/unleash?tab=readme-ov-file#unleash-sdks
To connect your application to Unleash you’ll need to use a client SDK for your programming language.要將您的應用程序連接到 Unleash,您需要使用適用于您的編程語言的客戶端 SDK。
官方服務端 SDK:
- Go SDK
- Java SDK
- Node.js SDK
- PHP SDK
- Python SDK
- Ruby SDK
- Rust SDK
- .NET SDK
官方前端 SDK:
The front-end SDKs connect via Unleash Edge in order to ensure privacy, scalability and security.前端 SDK 通過 Unleash Edge 連接,以確保隱私、可擴展性和安全性。
- Android Proxy SDK
- Flutter Proxy SDK
- iOS Proxy SDK
- JavaScript Proxy SDK
- React Proxy SDK
- Svelte Proxy SDK
- Vue Proxy SDK
開放API Tokens訪問
官方文檔:https://docs.getunleash.io/reference/api-tokens-and-client-keys
- 后端服務(如 Go) → 選擇
Server-side SDK (CLIENT)
Token。 - 前端/移動端 → 選擇
Client-side SDK (FRONTEND)
Token。
Server-side SDK (CLIENT)
Token 默認具有 讀取權限,可以查詢所有 Toggles 的配置。
Client-side SDK (FRONTEND)
Token 可能無法訪問某些敏感接口(如 /admin
或 /evaluate
)。
default:production.5050d6c03962ca79170b3360fc8bf0bb3ccc36e1e50ffe5dc88c7257
在 Unleash 中創建 Token 時,選擇 Token 類型 取決于你的使用場景。根據你的描述,你正在調試一個 Go 語言后端服務(通過 curl
調用 Unleash API),因此應該選擇:
curl
調用的是 Unleash 的 Server API(如/api/client/features
),屬于后端調試行為。- 需要讀取 Feature Toggles 的完整配置(包括
enabled
狀態、variants
、payload
等)。
Server-side SDK (CLIENT)
- 用于 后端服務(如 Go、Node.js、Java 等)連接 Unleash。
- 你的代碼中通過
unleash.GetVariant
調用 Unleash,屬于 Server-side SDK 的使用方式。
查詢所有 Feature Toggles
curl -X GET \-H "Authorization: YOUR_SERVER_SIDE_TOKEN" \"http://unleash.example.com/api/client/features"
查詢特定 Toggle
curl -X GET \-H "Authorization: Bearer YOUR_SERVER_SIDE_TOKEN" \"http://unleash.example.com/api/client/features/FEATURE_NAME"
API token types
官方文檔:https://docs.getunleash.io/reference/api-tokens-and-client-keys
Client tokens
客戶端 token 的作用域限定為一個或多個項目和一個環境。創建客戶端 token 時,您可以授予其對特定項目列表或所有當前或未來項目的訪問權限。客戶端 token 是機密信息,不得向最終用戶公開。
Client tokens cannot be used in frontend SDKs; use frontend tokens instead.
客戶端 token 不能在前端 SDK 中使用;請改用 前端 token。
Frontend tokens
使用前端 token 將 前端 SDK 通過 Unleash Frontend API 或 Unleash Edge 連接到 Unleash。它們授予用戶以下權限:
- Reading enabled flags for a given context針對給定上下文的讀取啟用標志
- Registering applications with the Unleash server向 Unleash 服務器注冊應用程序
- Sending usage metrics
前端令牌的作用域限定為一個或多個項目以及單個環境。創建前端令牌時,您可以授予其對特定項目列表的訪問權限,或授予其對所有當前或未來項目的訪問權限。前端令牌不被認為是秘密的,可以安全地暴露在客戶端。
前端令牌不能在服務器端 SDK 中使用;請改用 客戶端令牌。
Personal access tokens
個人訪問令牌反映了創建它們的用戶所擁有的權限。如果用戶的權限發生更改(例如通過添加自定義角色),令牌會自動更新以匹配新的權限。 您可以使用個人訪問令牌進行測試、調試或為自動化工具提供臨時訪問權限。
當您使用個人訪問令牌修改資源時,事件會記錄該操作的令牌創建者的姓名。
具有生命周期的個人訪問令牌會在過期后失效并停止工作。雖然您可以將令牌設置為永不過期,但我們建議使用具有過期日期的令牌,以遵循安全最佳實踐。
個人訪問令牌不適用于客戶端 SDK,因為它們未綁定到環境,可能會過期或其權限可能會更改。請改用 客戶端令牌。
Service account tokens
服務帳戶令牌為集成和自動化工具提供 API 訪問權限。 要了解更多信息,請訪問服務帳戶。
使用 Edge 將客戶端 SDK 連接到 Unleash
To connect a client-side SDK to Unleash using Unleash Edge, you need both a client and frontend token:要想使用 Unleash Edge 將客戶端 SDK 連接到 Unleash,你需要一個 客戶端 token 和一個 前端 token
- 客戶端 SDK 需要一個前端 token 才能與 Edge 通信。
- Edge 需要一個客戶端 token 才能與 Unleash 服務器通信。
go sdk demo
package mainimport ("fmt""log""net/http""time""github.com/Unleash/unleash-client-go/v3""github.com/Unleash/unleash-client-go/v3/context"
)func main() {// 初始化 Unleash 客戶端err := unleash.Initialize(unleash.WithAppName("my-app"),unleash.WithUrl("http://127.0.0.1:4242/api"),unleash.WithCustomHeaders(http.Header{"Authorization": []string{"x:x.xxx"},}),unleash.WithRefreshInterval(5*time.Second),unleash.WithMetricsInterval(5*time.Second),unleash.WithListener(&unleash.DebugListener{}),)if err != nil {log.Fatalf("初始化失敗: %v", err)}// 設置超時等待ready := make(chan struct{})go func() {unleash.WaitForReady()close(ready)}()// 等待就緒或超時select {case <-ready:fmt.Println("Unleash client is ready")case <-time.After(10 * time.Second):log.Fatal("Timeout waiting for Unleash client to be ready")}// 測試用例: 基于參考代碼的請求上下文testContext("測試請求", context.Context{UserId: "123",Properties: map[string]string{"UserId": "123"},})// 保持程序運行一段時間以觀察結果time.Sleep(15 * time.Second)
}func testContext(name string, ctx context.Context) {isEnabled := unleash.IsEnabled("someToggle", unleash.WithContext(ctx))fmt.Printf("\n=== %s ===\n", name)fmt.Printf("Feature Enabled: %v\n", isEnabled)fmt.Printf("Context:\n")fmt.Printf(" UserId: %s\n", ctx.UserId)fmt.Printf(" Properties:\n")for k, v := range ctx.Properties {fmt.Printf(" %s: %s\n", k, v)}// 獲取變體信息variant := unleash.GetVariant("someToggle", unleash.WithVariantContext(ctx))if variant != nil {fmt.Printf("\nVariant Information:\n")fmt.Printf(" Name: %s\n", variant.Name)fmt.Printf(" Enabled: %v\n", variant.Enabled)if variant.Enabled {fmt.Printf(" Payload Type: %s\n", variant.Payload.Type)fmt.Printf(" Payload Value: %s\n", variant.Payload.Value)}} else {fmt.Println("\nNo variant returned")}
}