Självstudie: Köra experiment med variantfunktionsflaggor (förhandsversion)

Att köra experiment i ditt program kan hjälpa dig att fatta välgrundade beslut för att förbättra appens prestanda och användarupplevelse. I den här guiden får du lära dig hur du konfigurerar och kör experiment i ett App Configuration Store. Du lär dig hur du samlar in och mäter data med hjälp av funktionerna i App Configuration, Application Insights (förhandsversion) och Split Experimentation Workspace (förhandsversion).

På så sätt kan du fatta datadrivna beslut för att förbättra ditt program.

Kommentar

Ett snabbt sätt att starta experimenteringsresan är att köra azd-exemplet Quote of the Day. Den här lagringsplatsen innehåller ett omfattande exempel, komplett med Azure-resursetablering och ett första experiment, om hur du integrerar Azure App Configuration med dina .NET-program för att köra experiment.

I den här kursen får du:

  • Skapa en variantfunktionsflagga
  • Lägga till en Application Insights-resurs i ditt arkiv
  • Lägga till en arbetsyta för delningsexperiment i ditt lager
  • Konfigurera en app för att köra ett experiment
  • Aktivera telemetri och skapa ett experiment i din variantfunktionsflagga
  • Skapa mått för experimentet
  • Hämta experimenteringsresultat

Förutsättningar

Skapa en variantfunktionsflagga (förhandsversion)

Skapa en variantfunktionsflagga med namnet Greeting med två varianter, Av och , enligt beskrivningen i snabbstarten Funktionsflagga.

Ansluta en Application Insights-resurs (förhandsversion) till konfigurationsarkivet

Om du vill köra ett experiment måste du först ansluta en arbetsytebaserad Application Insights-resurs till appkonfigurationsarkivet. När du ansluter den här resursen till appkonfigurationsarkivet konfigureras konfigurationsarkivet med telemetrikällan för experimenteringen.

  1. Välj Telemetri Application Insights (förhandsversion) i appkonfigurationsarkivet.>

    Skärmbild av Azure Portal genom att lägga till en Application Insights i en butik.

  2. Välj den Application Insights-resurs som du vill använda som telemetriprovider för dina variantfunktionsflaggor och program och välj Spara. Om du inte har någon Application Insights-resurs skapar du en genom att välja Skapa ny. Mer information om hur du fortsätter finns i Skapa en worskpace-baserad resurs. I Application Insights (förhandsversion) läser du sedan in listan över tillgängliga Application Insights-resurser igen och väljer din nya Application Insights-resurs.

  3. Ett meddelande anger att Application Insights-resursen har uppdaterats för App Configuration Store.

Ansluta en arbetsyta för delade experiment (förhandsversion) till din butik

Om du vill köra experiment i Azure App Configuration använder du Arbetsytan Dela experimentering. Följ stegen nedan för att ansluta en arbetsyta för delade experiment till din butik.

  1. I appkonfigurationsarkivet väljer du Experimentation>Split Experimentation Workspace (förhandsversion) på den vänstra menyn.

    Skärmbild av Azure Portal genom att lägga till en arbetsyta för delade experiment i App Configuration Store.

  2. Välj en arbetsyta för delningsexperiment och spara sedan. Om du inte har en arbetsyta för delade experiment följer du snabbstarten Dela experimenteringsarbetsyta för att skapa en.

    Kommentar

    Den datakälla som valdes i arbetsytan Dela experimentering måste vara samma Application Insights-resurs som du valde i föregående steg.

  3. Ett meddelande anger att åtgärden lyckades.

Konfigurera en app för att köra ett experiment

Nu när du har anslutit Application Insights-resursen (förhandsversion) till App Configuration Store konfigurerar du en app för att köra experimentet (förhandsversion).

I det här exemplet skapar du en ASP.NET webbapp med namnet Offert för dagen. När appen läses in visas ett citattecken. Användare kan trycka på hjärtknappen för att gilla den. För att förbättra användarengagemanget vill du utforska om ett personligt hälsningsmeddelande ökar antalet användare som gillar offerten. Du skapar funktionsflaggan Greeting i Azure App Configuration med två varianter, Av och . Användare som får varianten Av ser en standardrubrik. Användare som får varianten får ett hälsningsmeddelande. Du samlar in och sparar telemetrin för dina användarinteraktioner i Application Insights. Med Split Experimentation Workspace kan du analysera experimentets effektivitet.

Skapa en app och lägg till användarhemligheter

  1. Öppna en kommandotolk och kör följande kod. Detta skapar ett nytt Razor Pages-program i ASP.NET Core, med individuell kontoautentisering, och placerar det i en utdatamapp med namnet QuoteOfTheDay.

    dotnet new razor --auth Individual -o QuoteOfTheDay
    
  2. I kommandotolken går du till mappen QuoteOfTheDay och kör följande kommando för att skapa en användarhemlighet för programmet. Den här hemligheten innehåller anslutningssträng för App Configuration.

    dotnet user-secrets set ConnectionStrings:AppConfiguration "<App Configuration Connection string>"
    
  3. Skapa en annan användarhemlighet som innehåller anslutningssträng för Application Insights.

    dotnet user-secrets set ConnectionStrings:AppInsights "<Application Insights Connection string>"
    

Uppdatera programkoden

  1. I QuoteOfTheDay.csproj lägger du till de senaste förhandsversionerna av SDK:erna för funktionshantering och appkonfiguration som nödvändiga paket.

    <PackageReference Include="Microsoft.Azure.AppConfiguration.AspNetCore" Version="8.0.0-preview.2" />
    <PackageReference Include="Microsoft.FeatureManagement.Telemetry.ApplicationInsights" Version="4.0.0-preview3" />
    <PackageReference Include="Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore" Version="4.0.0-preview3" />
    <PackageReference Include="Microsoft.FeatureManagement.AspNetCore" Version="4.0.0-preview3" />
    
  2. Lägg till appkonfigurationsprovidern under raden var builder = WebApplication.CreateBuilder(args);i Program.cs, som hämtar konfigurationen från Azure när programmet startar. Som standard innehåller metoden UseFeatureFlags alla funktionsflaggor utan etikett och anger en cacheförfallotid på 30 sekunder.

    builder.Configuration
        .AddAzureAppConfiguration(o =>
        {
            o.Connect(builder.Configuration.GetConnectionString("AppConfiguration"));
    
            o.UseFeatureFlags();
        });
    
  3. Lägg till följande med hjälp av instruktioner i Program.cs:

    using Microsoft.ApplicationInsights.AspNetCore.Extensions;
    using Microsoft.ApplicationInsights.Extensibility;
    using Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore;
    
  4. Under var builder.Configuration.AddAzureAppConfiguration anropas lägger du till:

    // Add Application Insights telemetry.
    builder.Services.AddApplicationInsightsTelemetry(
        new ApplicationInsightsServiceOptions
        {
            ConnectionString = builder.Configuration.GetConnectionString("AppInsights"),
            EnableAdaptiveSampling = false
        })
        .AddSingleton<ITelemetryInitializer, TargetingTelemetryInitializer>();
    

    Det här kodfragmentet utför följande åtgärder.

    • Lägger till en Application Insights-telemetriklient i programmet.
    • Lägger till en telemetriinitierare som lägger till målinformation i utgående telemetri.
    • Inaktiverar anpassningsbar sampling. Mer information om hur du inaktiverar anpassningsbar sampling finns i Felsökning.
  5. Skapa en ny fil med namnet ExampleTargetingContextAccessor.cs i rotmappen QuoteOfTheDay. Då skapas en ny klass med namnet ExampleTargetingContextAccessor. Klistra in innehållet nedan i filen.

    using Microsoft.FeatureManagement.FeatureFilters;
    
    namespace QuoteOfTheDay
    {
        public class ExampleTargetingContextAccessor : ITargetingContextAccessor
        {
            private const string TargetingContextLookup = "ExampleTargetingContextAccessor.TargetingContext";
            private readonly IHttpContextAccessor _httpContextAccessor;
    
            public ExampleTargetingContextAccessor(IHttpContextAccessor httpContextAccessor)
            {
                _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
            }
    
            public ValueTask<TargetingContext> GetContextAsync()
            {
                HttpContext httpContext = _httpContextAccessor.HttpContext;
                if (httpContext.Items.TryGetValue(TargetingContextLookup, out object value))
                {
                    return new ValueTask<TargetingContext>((TargetingContext)value);
                }
                List<string> groups = new List<string>();
                if (httpContext.User.Identity.Name != null)
                {
                    groups.Add(httpContext.User.Identity.Name.Split("@", StringSplitOptions.None)[1]);
                }
                TargetingContext targetingContext = new TargetingContext
                {
                    UserId = httpContext.User.Identity.Name ?? "guest",
                    Groups = groups
                };
                httpContext.Items[TargetingContextLookup] = targetingContext;
                return new ValueTask<TargetingContext>(targetingContext);
            }
        }
    }
    

    Den här klassen förklarar hur FeatureManagements mål hämtar kontexten för en användare. I det här fallet läser httpContext.User.Identity.Name den för och behandlar domänen för UserId e-postadressen som en Group.

  6. Gå tillbaka till Program.cs och lägg till följande using-instruktioner.

    using Microsoft.FeatureManagement.Telemetry;
    using Microsoft.FeatureManagement;
    using QuoteOfTheDay;
    
  7. Under var AddApplicationInsightsTelemetry anropades lägger du till tjänster för att hantera uppdatering av appkonfiguration, konfigurera funktionshantering, konfigurera mål för funktionshantering och aktivera funktionshantering för att publicera telemetrihändelser.

    builder.Services.AddHttpContextAccessor();
    
    // Add Azure App Configuration and feature management services to the container.
    builder.Services.AddAzureAppConfiguration()
        .AddFeatureManagement()
        .WithTargeting<ExampleTargetingContextAccessor>()
        .AddTelemetryPublisher<ApplicationInsightsTelemetryPublisher>();
    
  8. Under raden var app = builder.Build();lägger du till ett mellanprogram som utlöser appkonfigurationsuppdatering när det är lämpligt.

    // Use Azure App Configuration middleware for dynamic configuration refresh.
    app.UseAzureAppConfiguration();
    
  9. Under det lägger du till följande kod för att ge TargetingTelemetryInitializer åtkomst till målinformation genom att lagra den på HttpContext.

    // Add TargetingId to HttpContext for telemetry
    app.UseMiddleware<TargetingHttpContextMiddleware>();
    
  10. I QuoteOfTheDay>Pages>Shared>_Layout.cshtml, under där QuoteOfTheDay.styles.css läggs till, lägger du till följande rad för att lägga till css för version 5.15.3 av .font-awesome

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
    
  11. Öppna QuoteOfTheDay>Pages>Index.cshtml.cs och skriv över innehållet till offertappen.

    using Microsoft.ApplicationInsights;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    using Microsoft.FeatureManagement;
    
    namespace QuoteOfTheDay.Pages;
    
    public class Quote
    {
        public string Message { get; set; }
    
        public string Author { get; set; }
    }
    
    public class IndexModel(IVariantFeatureManagerSnapshot featureManager, TelemetryClient telemetryClient) : PageModel
    {
        private readonly IVariantFeatureManagerSnapshot _featureManager = featureManager;
        private readonly TelemetryClient _telemetryClient = telemetryClient;
    
        private Quote[] _quotes = [
            new Quote()
            {
                Message = "You cannot change what you are, only what you do.",
                Author = "Philip Pullman"
            }];
    
        public Quote? Quote { get; set; }
    
        public bool ShowGreeting { get; set; }
    
        public async void OnGet()
        {
            Quote = _quotes[new Random().Next(_quotes.Length)];
    
            Variant variant = await _featureManager.GetVariantAsync("Greeting", HttpContext.RequestAborted);
    
            ShowGreeting = variant.Configuration.Get<bool>();
        }
    
        public IActionResult OnPostHeartQuoteAsync()
        {
            string? userId = User.Identity?.Name;
    
            if (!string.IsNullOrEmpty(userId))
            {
                // Send telemetry to Application Insights
                _telemetryClient.TrackEvent("Like");
    
                return new JsonResult(new { success = true });
            }
            else
            {
                return new JsonResult(new { success = false, error = "User not authenticated" });
            }
        }
    }
    

    Detta PageModel väljer ett slumpmässigt citattecken, använder GetVariantAsync för att hämta varianten för den aktuella användaren och anger en variabel med namnet "ShowGreeting" till variantens värde. Hanterar PageModel även Post-begäranden, som anropar _telemetryClient.TrackEvent("Like");, som skickar en händelse till Application Insights med namnet Like. Den här händelsen kopplas automatiskt till användaren och varianten och kan spåras med mått.

  12. Öppna index.cshtml och skriv över innehållet för offertappen.

    @page
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
        ViewData["Username"] = User.Identity.Name;
    }
    
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            color: #333;
        }
    
        .quote-container {
            background-color: #fff;
            margin: 2em auto;
            padding: 2em;
            border-radius: 8px;
            max-width: 750px;
            box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
            display: flex;
            justify-content: space-between;
            align-items: start;
            position: relative;
        }
    
        .vote-container {
            position: absolute;
            top: 10px;
            right: 10px;
            display: flex;
            gap: 0em;
        }
    
        .vote-container .btn {
            background-color: #ffffff; /* White background */
            border-color: #ffffff; /* Light blue border */
            color: #333
        }
    
        .vote-container .btn:focus {
            outline: none;
            box-shadow: none;
        }
    
        .vote-container .btn:hover {
            background-color: #F0F0F0; /* Light gray background */
        }
    
        .greeting-content {
            font-family: 'Georgia', serif; /* More artistic font */
        }
    
        .quote-content p.quote {
            font-size: 2em; /* Bigger font size */
            font-family: 'Georgia', serif; /* More artistic font */
            font-style: italic; /* Italic font */
            color: #4EC2F7; /* Medium-light blue color */
        }
    </style>
    
    <div class="quote-container">
        <div class="quote-content">
            @if (Model.ShowGreeting)
            {
                <h3 class="greeting-content">Hi <b>@User.Identity.Name</b>, hope this makes your day!</h3>
            }
            else
            {
                <h3 class="greeting-content">Quote of the day</h3>
            }
            <br />
            <p class="quote">“@Model.Quote.Message”</p>
            <p>- <b>@Model.Quote.Author</b></p>
        </div>
    
        <div class="vote-container">
            <button class="btn btn-primary" onclick="heartClicked(this)">
                <i class="far fa-heart"></i> <!-- Heart icon -->
            </button>
        </div>
    
        <form action="/" method="post">
            @Html.AntiForgeryToken()
        </form>
    </div>
    
    <script>
        function heartClicked(button) {
            var icon = button.querySelector('i');
            icon.classList.toggle('far');
            icon.classList.toggle('fas');
    
            // If the quote is hearted
            if (icon.classList.contains('fas')) {
                // Send a request to the server to save the vote
                fetch('/Index?handler=HeartQuote', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
                    }
                });
            }
        }
    </script>
    

    Den här koden motsvarar användargränssnittet för att visa QuoteOfTheDay och hantera med hjälp av hjärtåtgärden på ett citattecken. Det använder det tidigare nämnda Model.ShowGreeting värdet för att visa olika saker för olika användare, beroende på deras variant.

Kompilera och köra appen

  1. I kommandotolken i mappen QuoteOfTheDay kör du: dotnet build.

  2. Kör: dotnet run --launch-profile https.

  3. Leta efter ett meddelande i formatet Now listening on: https://localhost:{port} i programmets utdata. Gå till den inkluderade länken i webbläsaren.

  4. När du visar det program som körs väljer du Registrera längst upp till höger för att registrera en ny användare.

    Skärmbild av appen Offert för dagen som visar Registrera.

  5. Registrera en ny användare med namnet user@contoso.com. Lösenordet måste innehålla minst sex tecken och innehålla ett tal och ett specialtecken.

  6. Välj länken Klicka här för att verifiera e-post när du har angett användarinformation.

  7. Registrera en andra användare med namnet userb@contoso.com, ange ett annat lösenord och verifiera det andra e-postmeddelandet.

    Kommentar

    Det är viktigt för den här självstudien att använda dessa namn exakt. Så länge funktionen har konfigurerats som förväntat bör de två användarna se olika varianter.

  8. Välj Logga in längst upp till höger för att logga in som userb (userb@contoso.com).

    Skärmbild av dagens offertapp med **Inloggning**.

  9. När du har loggat in bör du se ett userb@contoso.com särskilt meddelande när du visar appen.

    Skärmbild av appen Offert för dagen som visar ett särskilt meddelande för användaren.

    userb@contoso.com är den enda användaren som ser specialmeddelandet.

Aktivera telemetri och skapa ett experiment i din variantfunktionsflagga

Aktivera telemetri och skapa ett experiment i din variantfunktionsflagga genom att följa stegen nedan:

  1. I appkonfigurationsarkivet går du till Operations>Feature Manager.

  2. Välj snabbmenyn ... hela vägen till höger om din variantfunktionsflagga "Greeting" (Hälsning) och välj Redigera.

    Skärmbild av Azure Portal som redigerar en variantfunktionsflagga.

  3. Gå till fliken Telemetri och markera kryssrutan Aktivera telemetri.

  4. Gå till fliken Experiment , markera kryssrutan Skapa experiment och ge experimentet ett namn.

  5. Välj Granska + uppdatera och sedan Uppdatera.

  6. Ett meddelande anger att åtgärden lyckades. I Funktionshanteraren ska variantfunktionsflaggan ha ordet Aktiv under Experiment.

Skapa mått för experimentet

Ett mått i Arbetsytan Dela experimentering är ett kvantitativt mått på en händelse som skickas till Application Insights. Det här måttet hjälper till att utvärdera effekten av en funktionsflagga på användarens beteende och resultat.

När du uppdaterade appen tidigare lade _telemetryClient.TrackEvent("Like") du till i programkoden. Like är en telemetrihändelse som representerar en användaråtgärd, i det här fallet valet av knappen Hjärta. Den här händelsen skickas till Application Insights-resursen, som du ansluter till det mått som du ska skapa. Appen vi skapade anger bara en händelse, men du kan ha flera händelser och därefter flera mått. Flera mått kan också baseras på en enda Application Insight-händelse.

  1. Gå till resursen För delad experimenteringsarbetsyta. Under Konfigurationsexperimenteringsmått> väljer du Skapa.

  2. Välj eller ange följande information under Skapa ett experimenteringsmått och spara med Skapa.

    Skärmbild av Azure Portal, som skapar ett nytt experimenteringsmått.

    Inställning Exempelvärde beskrivning
    Namn Hjärtröstning Namnet på experimenteringsmåttet.
    Beskrivning Räkna antalet personer som väljer hjärtknappen när de ser ett särskilt meddelande, jämfört med när de inte gör det. Valfri beskrivning av måttet.
    Application Insights-händelsenamn Tycka om Namnet på Application Insights-händelsen. Det här namnet är skiftlägeskänsligt och det är namnet som anges i koden med _telemetryClient.TrackEvent("<Event-Name>").
    Mät som Antal Följande alternativ är tillgängliga:
    • Antal: räknar antalet gånger som händelsen utlöses av dina användare.
    • Genomsnitt: genomsnittligt värde för händelsen för dina användare.
    • Summera: lägger till värden för händelsen för dina användare. Visar det genomsnittliga summerade värdet.
    • Procent: beräknar procentandelen användare som utlöste händelsen.
    Önskad effekt Ökning Den här inställningen representerar det slutliga målet eller syftet med att mäta ditt skapade mått.

    I den här självstudien är vår hypotes att fler användare klickar på den hjärtformade liknande knappen när det finns ett särskilt meddelande bredvid Dagens citat. Programkoden spårar det här klicket som en händelse med namnet Like. Programmet skickar like-händelsen som telemetri till Application Insights och den önskade effekten för det här experimentet är att se en ökning av antalet användarklick (mätt som Antal) i hjärtröstningen för att kunna verifiera den angivna hypotesen. Om antalet klick på knappen minskar trots att det särskilda meddelandet visas för den allokerade målgruppen, ogiltigförklaras hypotesen för det här experimentet.

  3. När det nya måttet har skapats visas det i portalen. Du kan redigera den eller ta bort den genom att välja snabbmenyn (...) till höger på skärmen.

    Skärmbild av Azure Portal som visar ett experimenteringsmått.

Hämta experimenteringsresultat

Om du vill testa ditt nyligen konfigurerade experiment och generera resultat som du kan analysera simulerar du viss trafik till programmet och väntar mellan 10 och 15 minuter.

Om du vill visa resultatet av experimentet går du till Funktionshanteraren och klickar på ...>Experimentera eller välj länken Aktiv i kolumnen Experiment. Den här kolumnen visas inte som standard. Om du vill visa den väljer du Hantera vy>Redigera kolumner>Lägg till kolumnexperiment> och Använd i Funktionshanteraren.

På resultatsidan väljs en version av experimentet, en baslinje att jämföra resultaten med och en jämförelsevariant som standard. Om det behövs ändrar du standardvärdena enligt dina önskemål och väljer sedan Använd för att visa resultatet av experimentet.

Skärmbild av Azure Portal som visar ett experimentresultat.

Skärmbilden ovan visar att experimentet hade önskat resultat, med varianten På för Heart Vote som resulterade i 560,62 % fler Hjärtröster än Av-varianten.

Alla ändringar i en variantfunktionsflagga genererar en ny version av experimentet, som du kan välja för att visa resultatet.

Kommentar

För att få experimenteringsresultat behöver du minst 30 händelser per variant, men vi föreslår att du har mer än den minsta samplingsstorleken för att se till att experimenteringen ger tillförlitliga resultat.

Kommentar

Application Insights-sampling är aktiverat som standard och kan påverka dina experimenteringsresultat. I den här självstudien rekommenderar vi att du inaktiverar sampling i Application Insights. Läs mer om sampling i Application Insights.

Gå vidare

Mer information om experimenteringsbegreppen finns i följande dokument.

Fortsätt till följande dokument för den fullständiga funktionskörningen i .NET-funktionshanteringsbiblioteket.