Snabbstart: Skapa ett serverlöst arbetsflöde med Durable Functions

I den här snabbstarten använder du kommandoradsverktygen Azure Developer för att skapa ett serverlöst arbetsflöde som samordnar flera uppgifter som körs parallellt. Du skapar resurser i Azure, verifierar koden lokalt och distribuerar den sedan till en ny serverless funktionsapp som körs i en Flex Consumption-plan i Azure Functions.

Projektet använder Azure Developer CLI (azd) för att förenkla distributionen av din kod till Azure. Den här distributionen följer aktuella metodtips för säkra och skalbara Azure Functions distributioner. Den här snabbstarten visar fan-out/fan-in-mönstret i Durable Functions, ett tillägg som orkestrerar tillståndskänsliga arbetsflöden med varaktig körning. Exemplet använder Durable Task Scheduler, en fullt hanterad backend för Durable Functions som ersätter Azure Storage-backend. Exemplet hämtar artikeltitlar parallellt – orkestreringen fläktar ut till flera aktiviteter som körs samtidigt och sedan samlas in för att aggregera resultaten.

Som standard följer Flex Consumption-planen en pay-for-what-you-use faktureringsmodell, vilket innebär att slutförandet av den här snabbstarten medför en liten kostnad på några USD cent eller mindre i ditt Azure konto.

Förutsättningar

Initiera projektet

Använd kommandot azd init för att skapa ett lokalt Durable Functions kodprojekt från en mall.

  1. Kör det här azd init kommandot i en tom mapp i den lokala terminalen eller kommandotolken:

    azd init --template durable-functions-quickstart-dotnet-azd -e dfquickstart-dotnet
    

    Det här kommandot hämtar projektfilerna från lagringsplatsen template och initierar projektet i en ny mapp. Flaggan -e anger ett namn för den aktuella miljön. I azdbehåller miljön en unik distributionskontext för din app och du kan definiera mer än en. Miljönamnet används också i namnet på den resursgrupp som du skapar i Azure.

  2. Byt till projektkatalogen och navigera sedan till appmappen fanoutfanin :

    cd durable-functions-quickstart-dotnet-azd/fanoutfanin
    
  1. Kör det här azd init kommandot i en tom mapp i den lokala terminalen eller kommandotolken:

    azd init --template durable-functions-quickstart-python-azd -e dfquickstart-python
    

    Det här kommandot hämtar projektfilerna från lagringsplatsen template och initierar projektet i en ny mapp. Flaggan -e anger ett namn för den aktuella miljön. I azdbehåller miljön en unik distributionskontext för din app och du kan definiera mer än en. Miljönamnet används också i namnet på den resursgrupp som du skapar i Azure.

  2. Byt till projektkatalogen och navigera sedan till appmappen src :

    cd durable-functions-quickstart-python-azd/src
    
  1. Kör det här azd init kommandot i en tom mapp i den lokala terminalen eller kommandotolken:

    azd init --template durable-functions-quickstart-typescript-azd -e dfquickstart-typescript
    

    Det här kommandot hämtar projektfilerna från lagringsplatsen template och initierar projektet i en ny mapp. Flaggan -e anger ett namn för den aktuella miljön. I azdbehåller miljön en unik distributionskontext för din app och du kan definiera mer än en. Miljönamnet används också i namnet på den resursgrupp som du skapar i Azure.

  2. Byt till projektkatalogen och navigera sedan till appmappen src :

    cd durable-functions-quickstart-typescript-azd/src
    
  1. Kör det här azd init kommandot i en tom mapp i den lokala terminalen eller kommandotolken:

    azd init --template durable-functions-quickstart-java-azd -e dfquickstart-java
    

    Det här kommandot hämtar projektfilerna från lagringsplatsen template och initierar projektet i en ny mapp. Flaggan -e anger ett namn för den aktuella miljön. I azdbehåller miljön en unik distributionskontext för din app och du kan definiera mer än en. Miljönamnet används också i namnet på den resursgrupp som du skapar i Azure.

  2. Ändra till projektkatalogen:

    cd durable-functions-quickstart-java-azd
    
  1. Kör det här azd init kommandot i en tom mapp i den lokala terminalen eller kommandotolken:

    azd init --template durable-functions-quickstart-javascript-azd -e dfquickstart-javascript
    

    Det här kommandot hämtar projektfilerna från lagringsplatsen template och initierar projektet i en ny mapp. Flaggan -e anger ett namn för den aktuella miljön. I azdbehåller miljön en unik distributionskontext för din app och du kan definiera mer än en. Miljönamnet används också i namnet på den resursgrupp som du skapar i Azure.

  2. Byt till projektkatalogen och navigera sedan till appmappen src :

    cd durable-functions-quickstart-javascript-azd/src
    
  1. Kör det här azd init kommandot i en tom mapp i den lokala terminalen eller kommandotolken:

    azd init --template durable-functions-quickstart-powershell-azd -e dfquickstart-powershell
    

    Det här kommandot hämtar projektfilerna från lagringsplatsen template och initierar projektet i en ny mapp. Flaggan -e anger ett namn för den aktuella miljön. I azdbehåller miljön en unik distributionskontext för din app och du kan definiera mer än en. Miljönamnet används också i namnet på den resursgrupp som du skapar i Azure.

  2. Byt till projektkatalogen och navigera sedan till appmappen src :

    cd durable-functions-quickstart-powershell-azd/src
    

Etablera Azure-resurser

Detta projekt använder kommandot azd provision för att skapa de nödvändiga Azure-resurserna, inklusive en ny funktionsapp i en Flex Consumption-plan, en Durable Task Scheduler och en task hub.

Tip

Projektet innehåller en uppsättning Bicep-filer (i infra mappen) som azd använder för att skapa en säker distribution till en Flex-förbrukningsplan som följer bästa praxis.

  1. Gå tillbaka till rotprojektmappen (mappen som innehåller azure.yaml filen):

    cd ..
    
  1. Se till att du fortfarande är i rotmappen för projektet (mappen som innehåller azure.yaml filen).
  1. Kör detta kommando för att autentisera med ditt Azure-konto:

    azd auth login
    
  2. Kör det här kommandot från projektets rotmapp så att azd kan skapa de nödvändiga Azure-resurserna:

    azd provision
    

    Rotmappen innehåller den azure.yaml definitionsfil som krävs av azd.

  3. Ange följande nödvändiga distributionsparametrar när du uppmanas att göra det:

    Parameter Description
    Azure-prenumeration Prenumeration där dina resurser skapas. Om ditt konto har mer än en hyresgäst måste du först välja din hyresgäst.
    Azure-lokalisering Azure-region där du kan skapa resursgruppen som innehåller de nya Azure-resurserna. Endast regioner som för närvarande stöder Flex Consumption-planen visas.
    vnetEnabled Om man ska distribuera i ett virtuellt nätverk. För denna snabbstart, välj falsk.

    Kommandot azd provision använder dina svar på dessa prompts med Bicep-konfigurationsfilerna för att skapa och konfigurera dessa nödvändiga Azure-resurser:

    • Flex-förbrukningsplan och funktionsapp
    • Azure Storage (krävs) och Application Insights (rekommenderas)
    • Hållbar uppgiftsschemaläggare och uppgiftsnav
    • Åtkomstprinciper och roller för ditt konto
    • Tjänst-till-tjänst-anslutningar med hanterade identiteter (i stället för lagrade anslutningssträngar)

    När kommandot har slutförts visas länkar till de resurser som du har skapat.

    Provisioning kör också ett postprovisioneringsskript som genererar en local.settings.json fil i din appmapp. Denna fil innehåller anslutningsinställningarna för den distribuerade Durable Task Scheduler-endpointen, som du behöver för att köra projektet lokalt.

Starta Azurite

För att köra projektet lokalt behöver Functions-runtime en lokal lagringsemulator. Inställningen "AzureWebJobsStorage": "UseDevelopmentStorage=true" i local.settings.json-filen styr runtimen att använda Azurite för detta ändamål.

I ett nytt terminalfönster, kör detta kommando för att starta Azurite:

azurite --skipApiVersionCheck --location ~/azurite-data

Låt Azurite köras i detta terminalfönster medan du testar lokalt.

Kör i din lokala miljö

  1. I ditt ursprungliga terminalfönster går du till fanoutfanin-appmappen och startar Functions-värden:

    cd fanoutfanin
    func start
    

    När Funktionernas värd startar i den lokala projektmappen skriver den de lokala URL-slutpunkterna för dina HTTP-utlösta funktioner till terminalens utdata.

    Note

    Eftersom åtkomstnyckelauktorisering inte tillämpas när du kör lokalt behöver du ingen åtkomstnyckel för att anropa funktionen.

  2. I webbläsaren gör du en GET-begäran till slutpunkten som startar orkestreringen:

    http://localhost:7071/api/FetchOrchestration_HttpStart

    Den här begäran startar en ny orkestreringsinstans. Orkestreringen förgrenar sig till flera aktiviteter för att hämta titlarna på artiklar från Microsoft Learn parallellt. När aktiviteterna avslutas samlas orkestreringen in igen och returnerar titlarna som en formaterad sträng.

  1. I ditt ursprungliga terminalfönster går du till appens mapp src, skapar och aktiverar en virtuell miljö, installerar beroenden och startar Functions-värden:

    cd src
    

    Hur du skapar och aktiverar din virtuella miljö (namngiven .venv) beror på din terminal:

    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
    func start
    

    När Funktionernas värd startar i den lokala projektmappen skriver den de lokala URL-slutpunkterna för dina HTTP-utlösta funktioner till terminalens utdata.

    Note

    Eftersom åtkomstnyckelauktorisering inte tillämpas när du kör lokalt behöver du ingen åtkomstnyckel för att anropa funktionen.

  2. I webbläsaren gör du en GET-begäran till HTTP-startslutpunkten:

    http://localhost:7071/api/orchestrators/fetch_orchestration

    Den här begäran startar en ny orkestreringsinstans. Orkestreringen förgrenar sig till flera aktiviteter för att hämta titlarna på artiklar från Microsoft Learn parallellt. När aktiviteterna avslutas samlas orkestreringen in igen och returnerar titlarna som en formaterad sträng.

  1. I din ursprungliga terminal, gå till appmappen src , installera beroenden, bygg projektet och starta Functions-värden:

    cd src
    npm install
    npm run build
    func start
    

    När Funktionernas värd startar i den lokala projektmappen skriver den de lokala URL-slutpunkterna för dina HTTP-utlösta funktioner till terminalens utdata.

    Note

    Eftersom åtkomstnyckelauktorisering inte tillämpas när du kör lokalt behöver du ingen åtkomstnyckel för att anropa funktionen.

  2. I webbläsaren gör du en GET-begäran till HTTP-startslutpunkten:

    http://localhost:7071/api/orchestrators/fetchOrchestration

    Den här begäran startar en ny orkestreringsinstans. Orkestreringen förgrenar sig till flera aktiviteter för att hämta titlarna på artiklar från Microsoft Learn parallellt. När aktiviteterna avslutas samlas orkestreringen in igen och returnerar titlarna som en formaterad sträng.

  1. I ditt ursprungliga terminalfönster bygger du projektet och startar sedan Functions-värden från mappen med byggutdata:

    mvn clean package
    cd target/azure-functions/durable-functions-quickstart
    func start
    

    När Funktionernas värd startar i den lokala projektmappen skriver den de lokala URL-slutpunkterna för dina HTTP-utlösta funktioner till terminalens utdata.

    Note

    Eftersom åtkomstnyckelauktorisering inte tillämpas när du kör lokalt behöver du ingen åtkomstnyckel för att anropa funktionen.

  2. I webbläsaren gör du en GET-begäran till slutpunkten som startar orkestreringen:

    http://localhost:7071/api/FetchOrchestration_HttpStart

    Den här begäran startar en ny orkestreringsinstans. Orkestreringen förgrenar sig till flera aktiviteter för att hämta titlarna på artiklar från Microsoft Learn parallellt. När aktiviteterna avslutas samlas orkestreringen in igen och returnerar titlarna som en formaterad sträng.

  1. I den ursprungliga terminalen går du till appmappen src, installerar beroenden och startar Functions-värden:

    cd src
    npm install
    func start
    

    När Funktionernas värd startar i den lokala projektmappen skriver den de lokala URL-slutpunkterna för dina HTTP-utlösta funktioner till terminalens utdata.

    Note

    Eftersom åtkomstnyckelauktorisering inte tillämpas när du kör lokalt behöver du ingen åtkomstnyckel för att anropa funktionen.

  2. I webbläsaren gör du en GET-begäran till slutpunkten som startar orkestreringen:

    http://localhost:7071/api/FetchOrchestration_HttpStart

    Den här begäran startar en ny orkestreringsinstans. Orkestreringen förgrenar sig till flera aktiviteter för att hämta titlarna på artiklar från Microsoft Learn parallellt. När aktiviteterna avslutas samlas orkestreringen in igen och returnerar titlarna som en formaterad sträng.

  1. I ditt ursprungliga terminalfönster går du till src-appmappen och startar Functions-värden:

    cd src
    func start
    

    När Funktionernas värd startar i den lokala projektmappen skriver den de lokala URL-slutpunkterna för dina HTTP-utlösta funktioner till terminalens utdata.

    Note

    Eftersom åtkomstnyckelauktorisering inte tillämpas när du kör lokalt behöver du ingen åtkomstnyckel för att anropa funktionen.

  2. I webbläsaren gör du en GET-begäran till slutpunkten som startar orkestreringen:

    http://localhost:7071/api/FetchOrchestration_HttpStart

    Den här begäran startar en ny orkestreringsinstans. Orkestreringen förgrenar sig till flera aktiviteter för att hämta titlarna på artiklar från Microsoft Learn parallellt. När aktiviteterna avslutas samlas orkestreringen in igen och returnerar titlarna som en formaterad sträng.

  1. HTTP-slutpunkten returnerar ett JSON-svar med flera URL:er. Slutpunkten statusQueryGetUri ger orkestreringsstatus.

  2. Kopiera värdet statusQueryGetUri och klistra in det i webbläsaren eller HTTP-testverktyget för att kontrollera orkestreringens status. När orkestreringen är klar visas de hämtade artikelrubrikerna i svaret.

  3. När du är klar trycker du på Ctrl+C i terminalfönstret för att stoppa func värdprocessen.

  1. Kör deactivate för att stänga av den virtuella miljön.

Granska koden (valfritt)

Du kan granska koden som implementerar fan-out/fan-in-mönstret.

Aktiviteter för hämtning av rubriker spåras med hjälp av en dynamisk uppgiftslista. Raden await Task.WhenAll(parallelTasks); väntar på att alla anropade aktiviteter, som körs parallellt, ska slutföras. När du är klar aggregeras alla utdata som en formaterad sträng.

[Function(nameof(FetchOrchestration))]
public static async Task<string> RunOrchestrator(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    ILogger logger = context.CreateReplaySafeLogger(nameof(FetchOrchestration));
    logger.LogInformation("Fetching data.");
    var parallelTasks = new List<Task<string>>();
    
    // List of URLs to fetch titles from
    var urls = new List<string>
    {
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps",
    };

    // Run fetching tasks in parallel
    foreach (var url in urls)
    {
        Task<string> task = context.CallActivityAsync<string>(nameof(FetchTitleAsync), url);
        parallelTasks.Add(task);
    }
    
    // Wait for all the parallel tasks to complete before continuing
    await Task.WhenAll(parallelTasks);
   
    // Return fetched titles as a formatted string
    return string.Join("; ", parallelTasks.Select(t => t.Result));
}

Du kan granska hela mallprojektet här.

Aktiviteter för hämtning av rubriker spåras med hjälp av en dynamisk uppgiftslista. Raden yield context.task_all(tasks) väntar på att alla anropade aktiviteter, som körs parallellt, ska slutföras. När du är klar aggregeras alla utdata som en formaterad sträng.

    # List of URLs to fetch titles from
    urls = [
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps",
    ]
    
    # Run fetching tasks in parallel
    tasks = []
    for url in urls:
        task = context.call_activity("fetch_title", url)
        tasks.append(task)
    
    # Wait for all the parallel tasks to complete before continuing
    results = yield context.task_all(tasks)
    
    # Return fetched titles as a formatted string
    return "; ".join(results)


@myApp.activity_trigger(input_name="url")
async def fetch_title(url: str):
    """Activity function that fetches the title from a URL."""
    logger = logging.getLogger("FetchTitle")
    logger.info(f"Fetching from url {url}.")
    
    try:
        async with ClientSession() as session:

Du kan granska hela mallprojektet här.

Aktiviteter för hämtning av rubriker spåras med hjälp av en dynamisk uppgiftslista. Raden yield context.df.Task.all(parallelTasks) väntar på att alla anropade aktiviteter, som körs parallellt, ska slutföras. När du är klar aggregeras alla utdata som en formaterad sträng.

    const urls = [
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps",
    ];

    // Run fetching tasks in parallel
    const parallelTasks = [];
    for (const url of urls) {
        const task = context.df.callActivity(fetchTitleActivityName, url);
        parallelTasks.push(task);
    }

    // Wait for all the parallel tasks to complete before continuing
    const results: string[] = yield context.df.Task.all(parallelTasks);

    // Return fetched titles as a formatted string
    return results.join("; ");
};
df.app.orchestration("fetchOrchestration", fetchOrchestration);

const fetchTitleAsync: ActivityHandler = async function (
    url: string,
    context: InvocationContext

Du kan granska hela mallprojektet här.

Aktiviteter för hämtning av rubriker spåras med hjälp av en dynamisk uppgiftslista. Raden ctx.allOf(parallelTasks).await() väntar på att alla anropade aktiviteter, som körs parallellt, ska slutföras. När du är klar aggregeras alla utdata som en formaterad sträng.

@FunctionName("FetchOrchestration")
public String runOrchestrator(
        @DurableOrchestrationTrigger(name = "taskOrchestrationContext") TaskOrchestrationContext ctx) {

    List<String> urls = List.of(
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps"
    );

    // Fan out: run fetching tasks in parallel
    List<Task<String>> parallelTasks = urls.stream()
        .map(url -> ctx.callActivity("FetchTitle", url, String.class))
        .collect(Collectors.toList());

    // Fan in: wait for all parallel tasks to complete
    List<String> results = ctx.allOf(parallelTasks).await();

    // Return fetched titles as a formatted string
    return String.join("; ", results);
}

Du kan granska hela mallprojektet här.

Aktiviteter för hämtning av rubriker spåras med hjälp av en dynamisk uppgiftslista. Raden yield context.df.Task.all(parallelTasks) väntar på att alla anropade aktiviteter, som körs parallellt, ska slutföras. När du är klar aggregeras alla utdata som en formaterad sträng.

df.app.orchestration('fetchOrchestration', function* (context) {
    context.log("Fetching data.");

    const urls = [
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
        "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
        "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
        "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps",
    ];

    // Fan out: run fetching tasks in parallel
    const parallelTasks = urls.map(url => context.df.callActivity(activityName, url));

    // Fan in: wait for all parallel tasks to complete
    const results = yield context.df.Task.all(parallelTasks);

    // Return fetched titles as a formatted string
    return results.join("; ");
});

Du kan granska hela mallprojektet här.

Aktiviteter för hämtning av rubriker spåras med hjälp av en dynamisk uppgiftslista. Raden Wait-ActivityFunction -Task $parallelTasks väntar på att alla anropade aktiviteter, som körs parallellt, ska slutföras. När du är klar aggregeras alla utdata som en formaterad sträng.

param($Context)

$urls = @(
    "https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview",
    "https://learn.microsoft.com/azure/azure-functions/durable/durable-task-scheduler/durable-task-scheduler",
    "https://learn.microsoft.com/azure/azure-functions/functions-scenarios",
    "https://learn.microsoft.com/azure/azure-functions/functions-create-ai-enabled-apps"
)

# Fan out: run fetching tasks in parallel
$parallelTasks = @()
foreach ($url in $urls) {
    $parallelTasks += Invoke-DurableActivity -FunctionName 'FetchTitle' -Input $url -NoWait
}

# Fan in: wait for all parallel tasks to complete
$results = Wait-ActivityFunction -Task $parallelTasks

# Return fetched titles as a formatted string
$output = $results -join "; "
$output

Du kan granska hela mallprojektet här.

Efter att du verifierat dina funktioner lokalt är det dags att distribuera dem till Azure.

Distribuera till Azure

Kör detta kommando från rotmappen för projekt för att distribuera ditt kodprojekt till funktionsappen i Azure:

azd deploy

Kommandot azd deploy paketerar och distribuerar din kod till funktionsappen som skapats under provisioneringen. Efter att kommandot är klart startar appen och körs i det distribuerade paketet.

Anropa funktionen på Azure

Nu kan du anropa orkestreringsslutpunkten i Azure genom att göra en HTTP-begäran till dess URL. När dina funktioner körs i Azure framtvingas åtkomstnyckelauktorisering och du måste ange en funktionsåtkomstnyckel med din begäran.

Du kan använda Core Tools för att hämta URL-slutpunkten för HTTP-utlösaren som startar orkestreringen i Azure.

  1. I den lokala terminalen eller kommandotolken kör du följande kommandon för att hämta URL-slutpunktsvärdena:

    APP_NAME=$(azd env get-value AZURE_FUNCTION_NAME)
    func azure functionapp list-functions $APP_NAME --show-keys
    

    Kommandot azd env get-value hämtar funktionsappens namn från den lokala miljön. När du använder --show-keys alternativet med func azure functionapp list-functionsinnehåller det returnerade värdet Invoke URL: för varje slutpunkt alla nödvändiga åtkomstnycklar på funktionsnivå.

  2. Använd en webbläsare eller ett HTTP-testverktyg för att göra en GET-förfrågan till HTTP-start-endpointen för att starta orkestreringen i din funktionsapp som körs i Azure.

Åter driftsätt din kod

Kör azd deploy så många gånger du behöver för att distribuera koduppdateringar till din funktionsapp. Om du behöver uppdatera Azure-resurserna, kör azd provision igen.

Note

Det senaste distributionspaketet skriver alltid över distribuerade kodfiler.

Dina första svar på azd frågor och eventuella miljövariabler som genereras av azd lagras lokalt i din namngivna miljö. azd env get-values Använd kommandot för att granska alla variabler i din miljö som du använde när du skapade Azure-resurser.

Rensa resurser

När du är klar med funktionsappen och relaterade resurser använder du det här kommandot för att ta bort funktionsappen och dess relaterade resurser från Azure och undvika ytterligare kostnader:

azd down --no-prompt

Note

Alternativet --no-prompt instruerar azd dig att ta bort resursgruppen utan någon bekräftelse från dig.

Det här kommandot påverkar inte ditt lokala kodprojekt.