本指南說明如何將 Go 應用程式與 App Lifecycle Manager 功能旗標整合。您將瞭解如何搭配 flagd 供應商使用 OpenFeature SDK,評估由 App Lifecycle Manager 管理的旗標,以便動態控管 Go 服務中的功能可用性和行為。
本指南假設您已完成下列其中一個快速入門導覽課程,設定必要的 App Lifecycle Manager 資源 (例如 SaaS 產品、單元種類、單元、旗標和推出作業):
- 快速入門導覽課程:使用 App Lifecycle Manager (整合式) 部署功能旗標:如果您使用 App Lifecycle Manager 管理應用程式部署作業。
- 快速入門:使用獨立功能旗標:如果您獨立管理應用程式基礎架構,但想使用 App Lifecycle Manager 管理功能旗標。
必要條件
開始之前,請確認您具備以下項目:
- 已安裝 Go:1.23 以上版本。
- 已完成 App Lifecycle Manager 功能旗標快速入門:
已驗證
gcloud應用程式預設憑證 (ADC):Go 應用程式會使用 ADC 向 Google Cloud 服務進行驗證。如果在本機執行 (用於獨立用途或本機 Docker 測試),請確認您已在環境中完成驗證:gcloud auth application-default loginIAM 權限:執行 Go 應用程式的身分必須在
roles/saasconfig.viewer專案中具備 Google Cloud Identity and Access Management 角色,才能讀取旗標設定:gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member="user:YOUR_EMAIL_ADDRESS" \ --role="roles/saasconfig.viewer"請視情況替換
YOUR_PROJECT_ID和YOUR_EMAIL_ADDRESS。
瞭解重要環境變數
Go 應用程式會依據環境變數連線至正確的旗標設定,並評估預期的旗標。
FLAGD_SOURCE_PROVIDER_ID:指定要從 App Lifecycle Manager 服務擷取的功能旗標設定。必須是與裝置相關聯的FeatureFlagConfig完整資源名稱。- 「Format」(形式):
projects/PROJECT_ID/locations/LOCATION/featureFlagsConfigs/UNIT_ID - 示例:
projects/my-gcp-project/locations/us-central1/featureFlagsConfigs/my-app-instance-01
- 「Format」(形式):
設定 Go 專案
執行應用程式前,請先初始化模組,並新增必要的初始化和評估邏輯。
建立專案目錄:
mkdir go-featureflag-app cd go-featureflag-app go mod init go-featureflag-app建立應用程式程式碼:新增名為
main.go的檔案,並加入下列內容,初始化供應器及評估旗標。package main import ( "context" "fmt" "log" "os" flagd "github.com/open-feature/go-sdk-contrib/providers/flagd/pkg" "github.com/open-feature/go-sdk/openfeature" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/oauth" "google.golang.org/grpc/metadata" ) // GetNewFlagdProvider initializes a flagd provider configured for App Lifecycle Manager func GetNewFlagdProvider(ctx context.Context) (*flagd.Provider, error) { providerID := os.Getenv("FLAGD_SOURCE_PROVIDER_ID") if providerID == "" { return nil, fmt.Errorf("FLAGD_SOURCE_PROVIDER_ID environment variable is not set") } creds, err := oauth.NewApplicationDefault(ctx) if err != nil { return nil, err } // Interceptor to inject the Unit name into headers for regional routing routingInterceptor := func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("name=%s", providerID)) ctx = metadata.NewOutgoingContext(ctx, md) return streamer(ctx, desc, cc, method, opts...) } options := []flagd.ProviderOption{ flagd.WithHost("saasconfig.googleapis.com"), flagd.WithPort(443), flagd.WithInProcessResolver(), flagd.WithProviderID(providerID), flagd.WithGrpcDialOptionsOverride([]grpc.DialOption{ grpc.WithTransportCredentials(credentials.NewTLS(nil)), grpc.WithPerRPCCredentials(creds), grpc.WithStreamInterceptor(routingInterceptor), }), } return flagd.NewProvider(options...) } // InitializeFeatureManagement registers the provider globally func InitializeFeatureManagement(ctx context.Context) error { provider, err := GetNewFlagdProvider(ctx) if err != nil { return err } openfeature.SetProvider(provider) return nil } func main() { ctx := context.Background() InitializeFeatureManagement(ctx); // 1. Get Client client := openfeature.NewClient("simple-api") // 2. Create Evaluation Context evalCtx := openfeature.NewEvaluationContext() // 3. Evaluate Flag // Default to false if evaluation fails isEnhanced, err := client.BooleanValue(context.Background(), "enhanced-search", false, evalCtx) if err != nil { log.Printf("Flag evaluation failed: %v", err) } // 4. Return response if isEnhanced { fmt.Println("Enhanced search feature is enabled.") } else { fmt.Println("Enhanced search feature is disabled.") } }建立 go.mod:使用特定版本可確保穩定性。
module go-featureflag-app go 1.23 require ( github.com/open-feature/go-sdk v1.15.1 github.com/open-feature/go-sdk-contrib/providers/flagd v0.3.0 google.golang.org/grpc v1.74.2 golang.org/x/oauth2 v0.22.0 )取得依附元件:
go mod tidy go mod download
執行 Go 應用程式
您可以透過獨立設定在本機執行應用程式,也可以部署為容器。
獨立執行 (在本機)
設定環境變數:
export PROJECT_ID="your-gcp-project-id" export LOCATION_1="us-central1" export UNIT_ID="my-app-instance-01" export FLAGD_SOURCE_PROVIDER_ID="projects/${PROJECT_ID}/locations/${LOCATION_1}/featureFlagsConfigs/${UNIT_ID}"執行應用程式:
go run main.go
執行整合式 (容器化)
建立 Dockerfile:
FROM golang:1.23 as builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /go-featureflag-app . FROM gcr.io/distroless/static-debian11 WORKDIR / COPY --from=builder /go-featureflag-app /go-featureflag-app ENTRYPOINT ["/go-featureflag-app"]建構及推送映像檔:
export PROJECT_ID="your-gcp-project-id" docker build -t gcr.io/${PROJECT_ID}/my-go-app:latest . docker push gcr.io/${PROJECT_ID}/my-go-app:latest部署服務:更新單元藍圖以參照
gcr.io/${PROJECT_ID}/my-go-app:latest,並使用 App Lifecycle Manager 推出作業部署新版本。
驗證旗標變更
應用程式執行後,請確認應用程式是否正確評估旗標。
- 觀察初始值:確認輸出內容記錄的值對應於初始狀態。
- 在 App Lifecycle Manager 中更新旗標:使用 Google Cloud 控制台或
gcloud修改旗標行為。 - 驗證更新後的值:重新執行本機編譯,或觀察容器記錄,查看更新後的結果。
後續步驟
- 如需更多概念性詳細資料,請參閱 App Lifecycle Manager 功能旗標總覽。
- 瞭解如何使用 App Lifecycle Manager Rollouts 安全地部署標記。
- 查看主要的 App Lifecycle Manager 總覽。