Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Go-funktionshanteringsbiblioteket är ett sätt att utveckla och exponera programfunktioner baserat på funktionsflaggor. När en ny funktion har utvecklats har många program särskilda krav, till exempel när funktionen ska aktiveras och under vilka villkor. Det här biblioteket är ett sätt att definiera dessa relationer och integreras även i vanliga Go-kodmönster för att göra det möjligt att exponera dessa funktioner.
Funktionsflaggor är ett sätt för Go-program att aktivera eller inaktivera funktioner dynamiskt. Utvecklare kan använda funktionsflaggor i enkla användningsfall som villkorssatser.
Här är några av fördelarna med att använda Go-funktionshanteringsbiblioteket:
- En vanlig konvention för funktionshantering
- Låg barriär för inträde
- Källa för funktionsflaggor i Azure App Configuration
- Livscykelhantering för funktionsflagga
- Konfigurationsvärden kan ändras i realtid
- Enkla till komplexa scenarier som omfattas
- Aktivera/inaktivera funktioner
- Utvärdera funktionstillstånd dynamiskt baserat på anrop till server
Go-funktionshanteringsbiblioteket är öppen källkod. Mer information finns på GitHub-lagringsplatsen.
Funktionsflaggor
Funktionsflaggor kan antingen aktiveras eller inaktiveras. Status för en flagga kan villkoras med hjälp av funktionsfilter.
Filter för funktioner
Funktionsfilter definierar ett scenario för när en funktion ska aktiveras. När en funktion utvärderas för om den är på eller av bläddras listan över funktionsfilter igenom tills ett av filtren bestämmer att funktionen ska aktiveras. I det här läget anses funktionen vara aktiverad och genomströmning via funktionsfiltren stoppas. Om inget funktionsfilter anger att funktionen ska vara aktiverad anses den vara inaktiverad.
Ett funktionsfilter för Microsoft Edge-webbläsare kan till exempel utformas. Det här funktionsfiltret aktiverar alla funktioner som är kopplade till den, så länge en HTTP-begäran kommer från Microsoft Edge.
Konfiguration av funktionsflagga
Go-funktionshanteringen stöder användning av funktionsflaggor som definierats i Azure App Configuration av den inbyggda funktionsflaggaleverantören azappconfigsamt en utökningspunkt via FeatureFlagProvider gränssnittet för att använda funktionsflaggor som definierats av andra leverantörer.
import (
"context"
"log"
"github.com/Azure/AppConfiguration-GoProvider/azureappconfiguration"
"github.com/microsoft/Featuremanagement-Go/featuremanagement"
"github.com/microsoft/Featuremanagement-Go/featuremanagement/providers/azappconfig"
)
// ... ...
// Load Azure App Configuration
appConfig, err := azureappconfiguration.Load(ctx, authOptions, options)
if err != nil {
log.Fatalf("Failed to load configuration: %v", err)
}
// Create feature flag provider
featureFlagProvider, err := azappconfig.NewFeatureFlagProvider(appConfig)
if err != nil {
log.Fatalf("Error creating feature flag provider: %v", err)
}
// Create feature manager
featureManager, err := featuremanagement.NewFeatureManager(featureFlagProvider, nil)
if err != nil {
log.Fatalf("Error creating feature manager: %v", err)
}
Deklaration av funktionsflagga
I följande exempel visas det format som används för att konfigurera funktionsflaggor i en JSON-fil.
{
"feature_management": {
"feature_flags": [
{
"id": "FeatureT",
"enabled": true
},
{
"id": "FeatureU",
"enabled": false
},
{
"id": "FeatureV",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
}
}
]
}
}
Avsnittet feature_management i JSON-dokumentet används av konventionen för att läsa in inställningar för funktionsflagga. Funktionsflaggaobjekt måste anges i matrisen feature_flags under avsnittet feature_management .
I avsnittet ovan ser vi tre olika funktioner. En funktionsflagga har id och enabled egenskaper.
id är det namn som används för att identifiera och referera till funktionsflaggan. Egenskapen enabled anger det aktiverade tillståndet för funktionsflaggan. En funktion är AV om den är aktiverad är false. Om enabled är sant beror funktionens tillstånd på villkoren. Om det inte finns några villkor är funktionen PÅ. Om det finns villkor och de är uppfyllda är funktionen PÅ. Om det finns villkor och de inte uppfylls är funktionen AV. Villkorsegenskapen deklarerar de villkor som används för att dynamiskt aktivera funktionen. Funktioner definierar sina funktionsfilter i den client_filters matrisen.
FeatureV anger ett funktionsfilter med namnet Microsoft.TimeWindow. Det här filtret är ett exempel på ett konfigurerbart funktionsfilter. Vi kan se i exemplet att filtret har en Parameters egenskap. Den här egenskapen används för att konfigurera filtret. I det här fallet konfigureras start- och sluttiderna för funktionen som ska vara aktiv.
Det detaljerade schemat för feature_management avsnittet finns här.
Avancerat: Användning av kolon :är förbjuden i funktionsflaggans namn.
Av/på-deklaration
Följande kodfragment visar ett alternativt sätt att definiera en funktion för enkla av/på-funktioner.
{
"feature_management": {
"feature_flags": [
{
"id": "FeatureT",
"enabled": "true"
},
{
"id": "FeatureX",
"enabled": "false"
}
]
}
}
Kravtyp
Egenskapen requirement_type för en funktionsflagga används för att avgöra om filtren ska använda Any eller All logik när du utvärderar tillståndet för en funktion. Om requirement_type inte anges är Anystandardvärdet .
-
Anyinnebär att endast ett filter behöver utvärderas till sant för att funktionen ska aktiveras. -
Allinnebär att varje filter måste utvärderas till sant för att funktionen ska aktiveras.
En requirement_type av All ändrar traderingen. Om det inte finns några filter inaktiveras funktionen. Sedan bläddras funktionsfiltren igenom tills ett av filtren bestämmer att funktionen ska inaktiveras. Om inget filter anger att funktionen ska inaktiveras anses den vara aktiverad.
{
"feature_management": {
"feature_flags": [
{
"id": "FeatureW",
"enabled": "true",
"conditions": {
"requirement_type": "All",
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
},
{
"name": "Percentage",
"parameters": {
"Value": "50"
}
}
]
}
},
]
}
}
I exemplet ovan FeatureW anger en requirement_type av All, vilket innebär att alla dess filter måste utvärderas till true för att funktionen ska aktiveras. I det här fallet är funktionen aktiverad för 50 % av användarna under den angivna tidsperioden.
Consumption
Den grundläggande formen av funktionshantering är att kontrollera om en funktionsflagga är aktiverad och sedan utföra åtgärder baserat på resultatet. Kontroll av tillståndet för en funktionsflagga görs via FeatureManagers IsEnabled-metod.
// Create feature flag provider
featureFlagProvider, err := azappconfig.NewFeatureFlagProvider(appConfig)
if err != nil {
log.Fatalf("Error creating feature flag provider: %v", err)
}
// Create feature manager
featureManager, err := featuremanagement.NewFeatureManager(featureFlagProvider, nil)
if err != nil {
log.Fatalf("Error creating feature manager: %v", err)
}
// Check if feature is enabled
enabled, err := featureManager.IsEnabled("FeatureX")
if err != nil {
log.Printf("Error checking feature: %v", err)
return
}
if enabled {
// Do something
}
Implementera ett funktionsfilter
Genom att skapa ett funktionsfilter kan du aktivera funktioner baserat på kriterier som du definierar. För att implementera ett funktionsfilter FeatureFilter måste gränssnittet implementeras.
FeatureFilter har en metod med namnet Evaluate. När en funktion är associerad med ett filter Evaluate anropas metoden under utvärderingen. Om Evaluate returnerar trueanses funktionen vara aktiverad.
type FeatureFilter interface {
// Name returns the identifier for this filter
Name() string
// Evaluate determines whether a feature should be enabled based on the provided contexts
Evaluate(evalCtx FeatureFilterEvaluationContext, appCtx any) (bool, error)
}
type FeatureFilterEvaluationContext struct {
// FeatureName is the name of the feature being evaluated
FeatureName string
// Parameters contains the filter-specific configuration parameters
Parameters map[string]any
}
Följande kodfragment visar hur du implementerar ett anpassat funktionsfilter.
type MyCustomFilter struct{}
func (f *MyCustomFilter) Evaluate(ctx context.Context, context *FeatureFilterEvaluationContext) bool {
// Custom logic to determine if feature should be enabled
if satisfyCriteria() {
return true
}
return false
}
func (f *MyCustomFilter) Name() string {
return "MyCustomFilter"
}
Funktionsfilter registreras genom att tillhandahålla dem vid skapandet av FeatureManager. Om ett anpassat funktionsfilter behöver någon kontext kan de skickas via parametern FeatureFilterEvaluationContext .
// Register custom filters
options := &featuremanagement.Options{
Filters: []featuremanagement.FeatureFilter{
&MyCustomFilter{},
},
}
// Create feature manager with custom filters
featureManager, err := featuremanagement.NewFeatureManager(featureFlagProvider, options)
if err != nil {
log.Fatalf("Error creating feature manager: %v", err)
}
Filteraliasattribut
När ett funktionsfilter registreras för en funktionsflagga används dess namn som standardalias. Du kan åsidosätta den här identifieraren Name() genom att implementera metoden, som anger namnet som ska användas i konfigurationen när du refererar till filtret i en funktionsflagga.
Filter för funktioner saknas
Om en funktion har konfigurerats för att aktiveras för ett specifikt funktionsfilter och funktionsfiltret inte är registrerat returneras ett fel när funktionen utvärderas.
Inbyggda funktionsfilter
Det finns två funktionsfilter som medföljer featuremanagement paketet: TimeWindowFilter, och TargetingFilter.
Vart och ett av de inbyggda funktionsfiltren har sina egna parametrar. Här är listan över funktionsfilter tillsammans med exempel.
Microsoft.TimeWindow
Det här filtret ger möjlighet att aktivera en funktion baserat på ett tidsfönster. Om endast End anges betraktas funktionen som aktiverad fram till dess. Om endast Start anges betraktas funktionen som påslagen vid alla tidpunkter efter den tiden.
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
Microsoft.Targeting
Det här filtret ger möjlighet att aktivera en funktion för en målgrupp. En detaljerad förklaring av målinriktning finns i målinriktningsavsnittet nedan. Filterparametrarna innehåller ett Audience objekt som beskriver användare, grupper, exkluderade användare/grupper och en standardprocent av användarbasen som ska ha åtkomst till funktionen. Varje gruppobjekt som visas i Groups avsnittet måste också ange vilken procentandel av gruppens medlemmar som ska ha åtkomst. Om en användare anges i Exclusion avsnittet, antingen direkt eller om användaren finns i en exkluderad grupp, inaktiveras funktionen. Annars, om en användare anges direkt i Users-avsnittet, eller om användaren är i procentandelen som ingår i någon av grupputrullningarna, eller om användaren hamnar i standardprocenten av utrullningen, kommer den användaren att ha funktionen aktiverad.
"client_filters": [
{
"name": "Microsoft.Targeting",
"parameters": {
"Audience": {
"Users": [
"Jeff",
"Alicia"
],
"Groups": [
{
"Name": "Ring0",
"RolloutPercentage": 100
},
{
"Name": "Ring1",
"RolloutPercentage": 50
}
],
"DefaultRolloutPercentage": 20,
"Exclusion": {
"Users": [
"Ross"
],
"Groups": [
"Ring2"
]
}
}
}
}
]
Targeting
Målinriktning är en strategi för hantering av funktioner som gör det möjligt för utvecklare att etappvis rulla ut nya funktioner till sin användarbas. Strategin bygger på konceptet att rikta in sig på en uppsättning användare som kallas målgruppen. En målgrupp består av specifika användare, grupper, exkluderade användare/grupper och en angiven procentandel av hela användarbasen. De grupper som ingår i målgruppen kan delas upp ytterligare i procent av deras totala medlemmar.
Följande steg visar ett exempel på en progressiv distribution för en ny betafunktion:
- Enskilda användare Jeff och Alicia beviljas åtkomst till betaversionen.
- En annan användare, Mark, ber att få anmäla sig och inkluderas.
- Tjugo procent av en grupp som kallas "Ring1"-användare ingår i betaversionen.
- Antalet "Ring1"-användare som ingår i betaversionen ökar till 100 procent.
- Fem procent av användarbasen ingår i betaversionen.
- Distributionsprocenten höjs till 100 procent och funktionen lanseras helt.
Den här strategin för att lansera en funktion är inbyggd i biblioteket via det inkluderade funktionsfiltret Microsoft.Targeting .
Rikta in sig på en användare
Målfiltret förlitar sig på en målkontext för att utvärdera om en funktion ska aktiveras. Den här målkontexten innehåller information som vilken användare som för närvarande utvärderas och vilka grupper användaren befinner sig i. Målkontexten måste skickas direkt när IsEnabledWithAppContext anropas.
// ... ...
// Create targeting context
targetingCtx := featuremanagement.TargetingContext{
UserID: "test_user",
Groups: []string{"Ring1"},
}
// Check if feature is enabled for the user
enabled, err := featureManager.IsEnabledWithAppContext("Beta", targetingCtx)
if err != nil {
log.Printf("Error checking feature: %v", err)
return
}
if enabled {
// Feature is enabled for this user
}
Målundantag
När du definierar en målgrupp kan användare och grupper undantas från målgruppen. Undantag är användbara när en funktion distribueras till en grupp användare, men några användare eller grupper måste undantas från distributionen. Exkludering definieras genom att en lista över användare och grupper läggs till i målgruppens Exclusion egenskap.
"Audience": {
"Users": [
"Jeff",
"Alicia"
],
"Groups": [
{
"Name": "Ring0",
"RolloutPercentage": 100
}
],
"DefaultRolloutPercentage": 0,
"Exclusion": {
"Users": [
"Mark"
]
}
}
I exemplet ovan är funktionen aktiverad för användare med namnet Jeff och Alicia. Det är också aktiverat för användare i gruppen med namnet Ring0. Men om användaren heter Markinaktiveras funktionen, oavsett om de finns i gruppen Ring0 eller inte. Undantag prioriteras framför resten av målfiltret.
Varianter
När nya funktioner läggs till i ett program kan det hända att en funktion har flera olika föreslagna designalternativ. En vanlig lösning för att bestämma en design är någon form av A/B-testning. A/B-testning innebär att tillhandahålla en annan version av funktionen till olika segment i användarbasen och välja en version baserat på användarinteraktion. I det här biblioteket aktiveras den här funktionen genom att representera olika konfigurationer av en funktion med varianter.
Varianter gör det möjligt för en funktionsflagga att bli mer än en enkel på/av-flagga. En variant representerar ett värde för en funktionsflagga som kan vara en sträng, ett tal, ett booleskt objekt eller till och med ett konfigurationsobjekt. En funktionsflagga som deklarerar varianter bör definiera under vilka omständigheter varje variant ska användas, vilket beskrivs mer detaljerat i avsnittet Allokera varianter .
type Variant struct {
// Name uniquely identifies this variant
Name string
// ConfigurationValue holds the value for this variant
ConfigurationValue any
}
Hämta versioner
För varje funktion kan en variant hämtas med metoden FeatureManager's GetVariant . Varianttilldelningen är beroende av den användare som för närvarande utvärderas och den informationen hämtas från målkontexten som du skickade in.
targetingCtx := featuremanagement.TargetingContext{
UserID: "Adam",
}
variant, err := featureManager.GetVariant("TestVariants", targetingCtx)
if err != nil {
log.Printf("Error getting variant: %v", err)
return
}
if variant != nil {
variantConfiguration := variant.Configuration
// Do something with the resulting variant and its configuration
}
Deklaration av variantfunktionsflagga
Jämfört med normala funktionsflaggor har variantfunktionsflaggor ytterligare två egenskaper: variants och allocation. Egenskapen variants är en matris som innehåller de varianter som definierats för den här funktionen. Egenskapen allocation definierar hur dessa varianter ska allokeras för funktionen. Precis som när du deklarerar normala funktionsflaggor kan du konfigurera variantfunktionsflaggor i en JSON-fil. Här är ett exempel på en variantfunktionsflagga.
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"enabled": true,
"allocation": {
"default_when_enabled": "Small",
"group": [
{
"variant": "Big",
"groups": [
"Ring1"
]
}
]
},
"variants": [
{
"name": "Big"
},
{
"name": "Small"
}
]
}
]
}
}
Definiera varianter
Varje variant har två egenskaper: ett namn och en konfiguration. Namnet används för att referera till en specifik variant och konfigurationen är värdet för den varianten. Konfigurationen kan anges med hjälp av configuration_value egenskapen .
configuration_value är en infogad konfiguration som kan vara ett sträng-, tal-, booleskt eller konfigurationsobjekt. Om configuration_value inte anges är egenskapen Configuration hos varianten som returneras nil.
En lista över alla möjliga varianter definieras för varje funktion under egenskapen variants .
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"variants": [
{
"name": "Big",
"configuration_value": {
"Size": 500
}
},
{
"name": "Small",
"configuration_value": {
"Size": 300
}
}
]
}
]
}
}
Allokera varianter
Processen för att allokera en funktions varianter bestäms av allocation funktionens egenskap.
"allocation": {
"default_when_enabled": "Small",
"default_when_disabled": "Small",
"user": [
{
"variant": "Big",
"users": [
"Marsha"
]
}
],
"group": [
{
"variant": "Big",
"groups": [
"Ring1"
]
}
],
"percentile": [
{
"variant": "Big",
"from": 0,
"to": 10
}
],
"seed": "13973240"
},
"variants": [
{
"name": "Big",
"configuration_value": "500px"
},
{
"name": "Small",
"configuration_value": "300px"
}
]
Inställningen allocation för en funktion har följande egenskaper:
| Fastighet | Description |
|---|---|
default_when_disabled |
Anger vilken variant som ska användas när en variant begärs medan funktionen anses vara inaktiverad. |
default_when_enabled |
Anger vilken variant som ska användas när en variant begärs medan funktionen anses vara aktiverad och ingen annan variant har tilldelats användaren. |
user |
Anger en variant och en lista över användare som den varianten ska tilldelas till. |
group |
Anger en variant och en lista över grupper. Varianten tilldelas om användaren finns i minst en av grupperna. |
percentile |
Anger en variant och ett procentintervall som användarens beräknade procentandel måste passa in i för att den varianten ska tilldelas. |
seed |
Värdet som procentberäkningar för percentile baseras på. Procentberäkningen för en viss användare blir densamma för alla funktioner om samma seed värde används. Om inget seed anges skapas ett standardutsäde baserat på funktionsnamnet. |
Om funktionen inte är aktiverad tilldelar funktionshanteraren den variant som markerats som default_when_disabled till den aktuella användaren, vilket i det här fallet är Small .
Om funktionen är aktiverad kontrollerar funktionshanteraren allokeringarna user, group, och percentile i den angivna ordningen för att tilldela en variant. I det här exemplet, om användaren som utvärderas heter Marsha, i gruppen med namnet Ring1, eller om användaren råkar falla mellan 0 och 10:e percentilen, tilldelas den angivna varianten till användaren. I det här fallet returnerar alla tilldelade användare varianten Big . Om ingen av dessa allokeringar matchar tilldelas användaren varianten default_when_enabled , som är Small.
Allokeringslogik liknar funktionsfiltret Microsoft.Targeting , men det finns vissa parametrar som finns i mål som inte finns i allokering och vice versa. Resultatet av mål och allokering är inte relaterade.
Åsidosätta aktiverat tillstånd med en variant
Du kan använda varianter för att åsidosätta det aktiverade tillståndet för en funktionsflagga. Överstyrning ger varianter en möjlighet att utöka utvärderingen av en feature-flagga. När du anropar IsEnabledWithAppContext en flagga med varianter kontrollerar funktionshanteraren om den variant som tilldelats den aktuella användaren har konfigurerats för att åsidosätta resultatet. Åsidosättande görs med den valfria variantegenskapen status_override. Som standard är den här egenskapen inställd på None, vilket innebär att varianten inte påverkar om flaggan anses vara aktiverad eller inaktiverad. Genom att ställa in status_override till Enabled tillåts det att varianten, när den väljs, åsidosätter en flagga för att aktiveras. Inställningen status_override ger Disabled motsatt funktionalitet och inaktiverar därför flaggan när varianten väljs. En egenskap med ett enabled tillstånd av false kan inte överskridas.
Om du använder en funktionsflagga med binära varianter kan egenskapen status_override vara användbar. Det gör att du kan fortsätta använda API:er som IsEnabledaWithAppContext i ditt program, samtidigt som du drar nytta av de nya funktionerna som medföljer varianter, till exempel percentilallokering och startvärde.
{
"id": "MyVariantFeatureFlag",
"enabled": true,
"allocation": {
"percentile": [
{
"variant": "On",
"from": 10,
"to": 20
}
],
"default_when_enabled": "Off",
"seed": "Enhanced-Feature-Group"
},
"variants": [
{
"name": "On"
},
{
"name": "Off",
"status_override": "Disabled"
}
]
}
I exemplet ovan är funktionen alltid aktiverad. Om den aktuella användaren är i det beräknade percentilintervallet på 10 till 20 returneras varianten On . Annars returneras varianten Off och eftersom status_override är lika Disabledmed betraktas funktionen nu som inaktiverad.
Nästa steg
Om du vill lära dig hur du använder funktionsflaggor i dina program fortsätter du till följande snabbstarter.
Fortsätt till följande handledningar om du vill lära dig hur du använder funktionsfilter.