Dela via


Så använder du Azure WebJobs SDK för händelsedriven bakgrundsbearbetning

Den här artikeln innehåller vägledning om hur du arbetar med Azure WebJobs SDK. Om du vill komma igång med WebJobs direkt kan du läsa Kom igång med Azure WebJobs SDK.

WebJobs SDK-versioner

Det här är de viktigaste skillnaderna mellan version 3.x och version 2.x av WebJobs SDK:

Flera beskrivningar i den här artikeln innehåller exempel för både WebJobs version 3.x och WebJobs version 2.x.

Azure Functions bygger på WebJobs SDK.

  • Azure Functions version 2.x bygger på WebJobs SDK version 3.x.
  • Azure Functions version 1.x bygger på WebJobs SDK version 2.x.

Lagringsplatser för källkod för både Azure Functions och WebJobs SDK använder WebJobs SDK-numreringen. Flera avsnitt i den här artikeln länkar till Azure Functions-dokumentationen.

Mer information finns i Jämför WebJobs SDK och Azure Functions

WebJobs-värd

Värden är en körningscontainer för funktioner. Värden lyssnar efter utlösare och anropsfunktioner. I version 3.x, värden är en implementering av IHost. I version 2.x använder du objektet JobHost . Du skapar en värdinstans i koden och skriver kod för att anpassa dess beteende.

Det här är en viktig skillnad mellan att använda WebJobs SDK direkt och att använda det indirekt via Azure Functions. I Azure Functions styr tjänsten värden och du kan inte anpassa värden genom att skriva kod. Med Azure Functions kan du anpassa värdbeteendet via inställningarna i host.json-filen. Dessa inställningar är strängar, inte kod, och användningen av dessa strängar begränsar vilka typer av anpassningar du kan göra.

Värdanslutningar

WebJobs SDK söker efter Azure Storage- och Azure Service Bus-anslutningar i local.settings.json-filen när du kör lokalt eller i webbjobbets miljö när du kör i Azure. Som standard kräver WebJobs SDK en lagringsanslutning med namnet AzureWebJobsStorage.

När anslutningsnamnet matchas till ett enda exakt värde identifierar körningen värdet som en anslutningssträng, vilket vanligtvis innehåller en hemlighet. Informationen om en anslutningssträng beror på vilken tjänst du ansluter till. Ett anslutningsnamn kan dock också referera till en samling med flera konfigurationsobjekt, som är användbara för att konfigurera identitetsbaserade anslutningar. Miljövariabler kan behandlas som en samling med hjälp av ett delat prefix som slutar med dubbla understreck __. Gruppen kan sedan refereras genom att ange anslutningsnamnet till det här prefixet.

Egenskapen för en Azure Blob-utlösardefinition kan till exempel connection vara Storage1. Så länge det inte finns något enda strängvärde som konfigurerats av en miljövariabel med namnet Storage1kan en miljövariabel med namnet Storage1__blobServiceUri användas för att informera blobServiceUri anslutningens egenskap. Anslutningsegenskaperna skiljer sig åt för varje tjänst. Se dokumentationen för komponenten som använder anslutningen.

Identitetsbaserade anslutningar

Om du vill använda identitetsbaserade anslutningar i WebJobs SDK kontrollerar du att du använder de senaste versionerna av WebJobs-paket i projektet. Du bör också se till att du har en referens till Microsoft.Azure.WebJobs.Host.Storage. Följande är ett exempel på hur projektfilen kan se ut när du har gjort de här uppdateringarna:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net48</TargetFramework>
    <IsWebJobProject>true</IsWebJobProject>
    <WebJobName>$(AssemblyName)</WebJobName>
    <WebJobType>Continuous</WebJobType>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.41" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage.Queues" Version="5.3.1" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Host.Storage" Version="5.0.1" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
  </ItemGroup>

  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>

När du konfigurerar webbjobb i HostBuilder måste du inkludera ett anrop till AddAzureStorageCoreServices, eftersom det är det som gör AzureWebJobsStorage att och andra Storage-utlösare och bindningar kan använda identitet:

    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        // other configurations...
    });

Sedan kan du konfigurera AzureWebJobsStorage anslutningen genom att ange miljövariabler (eller Programinställningar när de finns i App Service):

Miljövariabel beskrivning Exempelvärde
AzureWebJobsStorage__blobServiceUri Dataplanets URI för blobtjänsten för lagringskontot med hjälp av HTTPS-schemat. <https:// storage_account_name.blob.core.windows.net>
AzureWebJobsStorage__queueServiceUri Dataplanets URI för kötjänsten för lagringskontot med hjälp av HTTPS-schemat. <https:// storage_account_name.queue.core.windows.net>

Om du anger konfigurationen på något annat sätt än miljövariabler, till exempel med en appsettings.json, måste du i stället ange strukturerad konfiguration för anslutningen och dess egenskaper:

{
    "AzureWebJobsStorage": {
        "blobServiceUri": "https://<storage_account_name>.blob.core.windows.net",
        "queueServiceUri": "https://<storage_account_name>.queue.core.windows.net"
    }
}

Du kan utelämna egenskapen queueServiceUri om du inte planerar att använda blobutlösare.

När koden körs lokalt används din utvecklaridentitet som standard enligt det beteende som beskrivs för DefaultAzureCredential.

När koden finns i Azure App Service används den konfiguration som visas ovan som standard för den systemtilldelade hanterade identiteten för resursen. Om du i stället vill använda en användartilldelad identitet som har tilldelats till appen måste du lägga till ytterligare egenskaper för anslutningen som anger vilken identitet som ska användas. Egenskapen credential (AzureWebJobsStorage__credential som en miljövariabel) ska anges till strängen "managedidentity". Egenskapen clientId (AzureWebJobsStorage__clientId som en miljövariabel) ska anges till klient-ID:t för den användartilldelade hanterade identiteten som ska användas. Som strukturerad konfiguration skulle det fullständiga objektet vara:

{
    "AzureWebJobsStorage": {
        "blobServiceUri": "https://<storage_account_name>.blob.core.windows.net",
        "queueServiceUri": "https://<storage_account_name>.queue.core.windows.net",
        "credential": "managedidentity",
        "clientId": "<user-assigned-identity-client-id>"
    }
}

Identiteten som används för AzureWebJobsStorage bör ha rolltilldelningar som ger den rollerna Storage Blob Data Owner, Storage Queue Data Contributor och Storage Account Contributor . Du kan utelämna både Storage Queue Data Contributor och Storage Account Contributor om du inte planerar att använda blobutlösare.

I följande tabell visas inbyggda roller som rekommenderas när du använder utlösare i bindningar i normal drift. Ditt program kan kräva ytterligare behörigheter baserat på den kod du skriver.

Bindning Exempel på inbyggda roller
Blob-utlösare Lagringsblobdataägare och lagringsködatadeltagare
Se ovan för krav på AzureWebJobsStorage också.
Blob (indata) Storage Blob Data-läsare
Blob (utdata) Storage Blob Data-ägare
Köutlösare Dataläsare för lagringskö, datameddelandeprocessor för lagringskö
Kö (utdata) Storage Queue Data Contributor, Storage Queue Data Message Sender
Service Bus-utlösare1 Azure Service Bus-datamottagare, Azure Service Bus-dataägare
Service Bus (utdata) Azure Service Bus-datasändare

1 För att utlösa från Service Bus-ämnen måste rolltilldelningen ha ett effektivt omfång för Service Bus-prenumerationsresursen. Om bara ämnet ingår uppstår ett fel. Vissa klienter, som Azure-portalen, exponerar inte Service Bus-prenumerationsresursen som ett omfång för rolltilldelning. I sådana fall kan Azure CLI användas i stället. Mer information finns i Inbyggda Azure-roller för Azure Service Bus.

Anslutningssträngar i version 2.x

Version 2.x av SDK:t kräver inget specifikt namn. Version 2.x låter dig använda dina egna namn för dessa anslutningssträng och låter dig lagra dem någon annanstans. Du kan ange namn i kod med hjälp av JobHostConfiguration, så här:

static void Main(string[] args)
{
    var _storageConn = ConfigurationManager
        .ConnectionStrings["MyStorageConnection"].ConnectionString;

    //// Dashboard logging is deprecated; use Application Insights.
    //var _dashboardConn = ConfigurationManager
    //    .ConnectionStrings["MyDashboardConnection"].ConnectionString;

    JobHostConfiguration config = new JobHostConfiguration();
    config.StorageConnectionString = _storageConn;
    //config.DashboardConnectionString = _dashboardConn;
    JobHost host = new JobHost(config);
    host.RunAndBlock();
}

Kommentar

Eftersom version 3.x använder standard-API:er för .NET Core-konfiguration. Det finns inget API för att ändra anslutningssträng namn. Se Utveckla och distribuera webbjobb med Hjälp av Visual Studio

Inställningar för värdutveckling

Du kan köra värden i utvecklingsläge för att göra den lokala utvecklingen mer effektiv. Här följer några av de inställningar som ändras automatiskt när du kör i utvecklingsläge:

Property Utvecklingsinställning
Tracing.ConsoleLevel TraceLevel.Verbose för att maximera loggutdata.
Queues.MaxPollingInterval Ett lågt värde för att säkerställa att kömetoder utlöses omedelbart.
Singleton.ListenerLockPeriod 15 sekunder för att underlätta snabb iterativ utveckling.

Processen för att aktivera utvecklingsläge beror på SDK-versionen.

Version 3.x

Version 3.x använder standard-ASP.NET Core-API:er. UseEnvironment Anropa metoden på instansenHostBuilder. Skicka en sträng med namnet development, som i det här exemplet:

static async Task Main()
{
    var builder = new HostBuilder();
    builder.UseEnvironment("development");
    builder.ConfigureWebJobs(b =>
            {
                b.AddAzureStorageCoreServices();
            });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Version 2.x

Klassen JobHostConfiguration har en UseDevelopmentSettings metod som aktiverar utvecklingsläge. I följande exempel visas hur du använder utvecklingsinställningar. Om du vill returnera config.IsDevelopment true när den körs lokalt anger du en lokal miljövariabel med namnet AzureWebJobsEnv med värdet Development.

static void Main()
{
    config = new JobHostConfiguration();

    if (config.IsDevelopment)
    {
        config.UseDevelopmentSettings();
    }

    var host = new JobHost(config);
    host.RunAndBlock();
}

Hantera samtidiga anslutningar (version 2.x)

I version 3.x, anslutningsgränsen är som standard oändliga anslutningar. Om du av någon anledning behöver ändra den här gränsen kan du använda MaxConnectionsPerServer egenskapen för WinHttpHandler klassen.

I version 2.x kontrollerar du antalet samtidiga anslutningar till en värd med hjälp av API:et ServicePointManager.DefaultConnectionLimit . I 2.x bör du öka det här värdet från standardvärdet 2 innan du startar webbjobbsvärden.

Alla utgående HTTP-begäranden som du gör från en funktion med hjälp HttpClient av flödet via ServicePointManager. När du har nått värdet som angetts i DefaultConnectionLimitServicePointManager börjar du köa begäranden innan du skickar dem. Anta att din DefaultConnectionLimit är inställd på 2 och att koden gör 1 000 HTTP-begäranden. Inledningsvis tillåts endast två begäranden till operativsystemet. De andra 998 står i kö tills det finns plats för dem. Det innebär att tidsgränsen HttpClient kan uppstå eftersom den verkar ha gjort begäran, men begäran skickades aldrig av operativsystemet till målservern. Så du kanske ser ett beteende som inte verkar vettigt: det tar 10 sekunder för din lokala HttpClient användare att slutföra en begäran, men tjänsten returnerar varje begäran på 200 ms.

Standardvärdet för ASP.NET program är Int32.MaxValue, och det kommer sannolikt att fungera bra för webbjobb som körs i en Grundläggande eller högre App Service-plan. WebJobs behöver vanligtvis inställningen Alltid på , och det stöds endast av Grundläggande och högre App Service-planer.

Om ditt webbjobb körs i en kostnadsfri eller delad App Service-plan begränsas ditt program av Sandbox-miljön för App Service, som för närvarande har en anslutningsgräns på 300. Med en gräns för obundna anslutningar i ServicePointManagerär det mer troligt att tröskelvärdet för sandbox-anslutning nås och att platsen stängs av. I så fall kan inställningen DefaultConnectionLimit till något lägre, t.ex. 50 eller 100, förhindra att detta händer och fortfarande ge tillräckligt dataflöde.

Inställningen måste konfigureras innan http-begäranden görs. Därför bör WebJobs-värden inte justera inställningen automatiskt. Det kan finnas HTTP-begäranden som inträffar innan värden startar, vilket kan leda till oväntat beteende. Den bästa metoden är att ange värdet omedelbart i metoden Main innan du initierar JobHost, som du ser här:

static void Main(string[] args)
{
    // Set this immediately so that it's used by all requests.
    ServicePointManager.DefaultConnectionLimit = Int32.MaxValue;

    var host = new JobHost();
    host.RunAndBlock();
}

Utlösare

WebJobs SDK stöder samma uppsättning utlösare och bindningar som används av Azure Functions. Observera att i WebJobs SDK är utlösare funktionsspecifika och inte relaterade till distributionstypen Webbjobb. Webbjobb med händelseutlösta funktioner som skapats med hjälp av SDK ska alltid publiceras som ett kontinuerligt webbjobb, med Always on aktiverat.

Funktioner måste vara offentliga metoder och måste ha ett utlösarattribut eller attributet NoAutomaticTrigger .

Automatiska utlösare

Automatiska utlösare anropar en funktion som svar på en händelse. Tänk på det här exemplet på en funktion som utlöses av ett meddelande som lagts till i Azure Queue Storage. Funktionen svarar genom att läsa en blob från Azure Blob Storage:

public static void Run(
    [QueueTrigger("myqueue-items")] string myQueueItem,
    [Blob("samples-workitems/{queueTrigger}", FileAccess.Read)] Stream myBlob,
    ILogger log)
{
    log.LogInformation($"BlobInput processed blob\n Name:{myQueueItem} \n Size: {myBlob.Length} bytes");
}

Attributet QueueTrigger instruerar körningen att anropa funktionen när ett kömeddelande visas i myqueue-items. Attributet Blob instruerar körningen att använda kömeddelandet för att läsa en blob i containern sample-workitems . Namnet på blobobjektet i containern samples-workitems hämtas direkt från köutlösaren som ett bindningsuttryck ({queueTrigger}).

Kommentar

En webbapp kan överskrida tidsgränsen efter 20 minuters inaktivitet och endast begäranden till den faktiska webbappen kan återställa timern. Om du visar appens konfiguration i Azure Portal eller skickar begäranden till webbplatsen för avancerade verktyg (https://<app_name>.scm.azurewebsites.net) återställs inte timern. Om du anger att webbappen som är värd för ditt jobb ska köras kontinuerligt, köras enligt ett schema eller använda händelsedrivna utlösare aktiverar du inställningen Alltid på på webbappens Azure-konfigurationssida. Inställningen Alltid på hjälper till att se till att den här typen av webbjobb körs på ett tillförlitligt sätt. Den här funktionen är endast tillgänglig på prisnivåerna Basic, Standard och Premium.

Manuella utlösare

Om du vill utlösa en funktion manuellt använder du NoAutomaticTrigger attributet enligt följande:

[NoAutomaticTrigger]
public static void CreateQueueMessage(
ILogger logger,
string value,
[Queue("outputqueue")] out string message)
{
    message = value;
    logger.LogInformation("Creating queue message: ", message);
}

Processen för att utlösa funktionen manuellt beror på SDK-versionen.

Version 3.x

static async Task Main(string[] args)
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        b.AddAzureStorage();
    });
    var host = builder.Build();
    using (host)
    {
        var jobHost = host.Services.GetService(typeof(IJobHost)) as JobHost;
        var inputs = new Dictionary<string, object>
        {
            { "value", "Hello world!" }
        };

        await host.StartAsync();
        await jobHost.CallAsync("CreateQueueMessage", inputs);
        await host.StopAsync();
    }
}

Version 2.x

static void Main(string[] args)
{
    JobHost host = new JobHost();
    host.Call(typeof(Program).GetMethod("CreateQueueMessage"), new { value = "Hello world!" });
}

Indata- och utdatabindningar

Indatabindningar är ett deklarativt sätt att göra data från Azure- eller tredjepartstjänster tillgängliga för din kod. Utdatabindningar är ett sätt att uppdatera data. Artikeln Kom igång visar ett exempel på var och en.

Du kan använda ett metodreturvärde för en utdatabindning genom att tillämpa attributet på metodens returvärde. Se exemplet i Använda azure-funktionens returvärde.

Bindningstyper

Processen för att installera och hantera bindningstyper beror på om du använder version 3.x eller version 2.x av SDK:et. Du hittar paketet som ska installeras för en viss bindningstyp i avsnittet "Paket" i den bindningstypens Azure Functions-referensartikel. Ett undantag är utlösare och bindning av filer (för det lokala filsystemet), som inte stöds av Azure Functions.

Version 3.x

I version 3.x ingår lagringsbindningarna i Microsoft.Azure.WebJobs.Extensions.Storage paketet. AddAzureStorage Anropa tilläggsmetoden i ConfigureWebJobs -metoden, som du ser här:

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
            {
                b.AddAzureStorageCoreServices();
                b.AddAzureStorage();
            });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Om du vill använda andra utlösar- och bindningstyper installerar du NuGet-paketet som innehåller dem och anropar Add<binding> tilläggsmetoden som implementerats i tillägget. Om du till exempel vill använda en Azure Cosmos DB-bindning installerar Microsoft.Azure.WebJobs.Extensions.CosmosDB och anropar AddCosmosDBdu , så här:

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
            {
                b.AddAzureStorageCoreServices();
                b.AddCosmosDB();
            });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Om du vill använda Timer-utlösaren eller filbindningen, som är en del av kärntjänsterna, anropar du tilläggsmetoderna AddTimers eller AddFiles .

Version 2.x

Dessa utlösare och bindningstyper ingår i version 2.x av Microsoft.Azure.WebJobs paketet:

  • Blobb-lagring
  • Queue Storage
  • Table Storage

Om du vill använda andra utlösar- och bindningstyper installerar du NuGet-paketet som innehåller dem och anropar en Use<binding> metod för JobHostConfiguration objektet. Om du till exempel vill använda en Timer-utlösare installerar Microsoft.Azure.WebJobs.Extensions och anropar UseTimers Main du metoden enligt följande:

static void Main()
{
    config = new JobHostConfiguration();
    config.UseTimers();
    var host = new JobHost(config);
    host.RunAndBlock();
}

Om du vill använda filbindningen installerar Microsoft.Azure.WebJobs.Extensions du och anropar UseFiles.

ExecutionContext

Med WebJobs kan du binda till en ExecutionContext. Med den här bindningen kan du komma åt ExecutionContext som en parameter i funktionssignaturen. Följande kod använder till exempel kontextobjektet för att komma åt anrops-ID:t, som du kan använda för att korrelera alla loggar som skapas av en viss funktionsanrop.

public class Functions
{
    public static void ProcessQueueMessage([QueueTrigger("queue")] string message,
        ExecutionContext executionContext,
        ILogger logger)
    {
        logger.LogInformation($"{message}\n{executionContext.InvocationId}");
    }
}

Processen för bindning till ExecutionContext beror på din SDK-version.

Version 3.x

AddExecutionContextBinding Anropa tilläggsmetoden i ConfigureWebJobs -metoden, som du ser här:

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
            {
                b.AddAzureStorageCoreServices();
                b.AddExecutionContextBinding();
            });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Version 2.x

Paketet Microsoft.Azure.WebJobs.Extensions som nämndes tidigare innehåller också en särskild bindningstyp som du kan registrera genom att anropa UseCore metoden. Med den här bindningen kan du definiera en ExecutionContext parameter i funktionssignaturen, som är aktiverad så här:

class Program
{
    static void Main()
    {
        config = new JobHostConfiguration();
        config.UseCore();
        var host = new JobHost(config);
        host.RunAndBlock();
    }
}

Bindningskonfiguration

Du kan konfigurera beteendet för vissa utlösare och bindningar. Processen för att konfigurera dem beror på SDK-versionen.

  • Version 3.x: Ange konfiguration när Add<Binding> metoden anropas i ConfigureWebJobs.
  • Version 2.x: Ange konfiguration genom att ange egenskaper i ett konfigurationsobjekt som du skickar till JobHost.

De här bindningsspecifika inställningarna motsvarar inställningarna i host.json-projektfilen i Azure Functions.

Du kan konfigurera följande bindningar:

Azure Cosmos DB-utlösarkonfiguration (version 3.x)

Det här exemplet visar hur du konfigurerar Azure Cosmos DB-utlösaren:

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        b.AddCosmosDB(a =>
        {
            a.ConnectionMode = ConnectionMode.Gateway;
            a.Protocol = Protocol.Https;
            a.LeaseOptions.LeasePrefix = "prefix1";

        });
    });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Mer information finns i artikeln om Azure Cosmos DB-bindning .

Event Hubs-utlösarkonfiguration (version 3.x)

Det här exemplet visar hur du konfigurerar Event Hubs-utlösaren:

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        b.AddEventHubs(a =>
        {
            a.BatchCheckpointFrequency = 5;
            a.EventProcessorOptions.MaxBatchSize = 256;
            a.EventProcessorOptions.PrefetchCount = 512;
        });
    });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Mer information finns i artikeln om Event Hubs-bindning .

Konfiguration av kölagringsutlösare

I följande exempel visas hur du konfigurerar kölagringsutlösaren.

Version 3.x

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        b.AddAzureStorage(a => {
            a.BatchSize = 8;
            a.NewBatchThreshold = 4;
            a.MaxDequeueCount = 4;
            a.MaxPollingInterval = TimeSpan.FromSeconds(15);
        });
    });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Mer information finns i artikeln Kölagringsbindning .

Version 2.x

static void Main(string[] args)
{
    JobHostConfiguration config = new JobHostConfiguration();
    config.Queues.BatchSize = 8;
    config.Queues.NewBatchThreshold = 4;
    config.Queues.MaxDequeueCount = 4;
    config.Queues.MaxPollingInterval = TimeSpan.FromSeconds(15);
    JobHost host = new JobHost(config);
    host.RunAndBlock();
}

Mer information finns i referensen host.json v1.x.

SendGrid-bindningskonfiguration (version 3.x)

Det här exemplet visar hur du konfigurerar SendGrid-utdatabindningen:

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        b.AddSendGrid(a =>
        {
            a.FromAddress.Email = "samples@functions.com";
            a.FromAddress.Name = "Azure Functions";
        });
    });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Mer information finns i artikeln SendGrid-bindning .

Service Bus-utlösarkonfiguration (version 3.x)

Det här exemplet visar hur du konfigurerar Service Bus-utlösaren:

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        b.AddServiceBus(sbOptions =>
        {
            sbOptions.MessageHandlerOptions.AutoComplete = true;
            sbOptions.MessageHandlerOptions.MaxConcurrentCalls = 16;
        });
    });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Mer information finns i artikeln om Service Bus-bindning .

Konfiguration för andra bindningar

Vissa typer av utlösare och bindningar definierar sina egna anpassade konfigurationstyper. Med filutlösaren kan du till exempel ange den rotsökväg som ska övervakas, som i följande exempel.

Version 3.x

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        b.AddFiles(a => a.RootPath = @"c:\data\import");
    });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Version 2.x

static void Main()
{
    config = new JobHostConfiguration();
    var filesConfig = new FilesConfiguration
    {
        RootPath = @"c:\data\import"
    };
    config.UseFiles(filesConfig);
    var host = new JobHost(config);
    host.RunAndBlock();
}

Bindande uttryck

I attributkonstruktorparametrar kan du använda uttryck som matchar värden från olika källor. I följande kod skapar till exempel sökvägen för BlobTrigger attributet ett uttryck med namnet filename. När den används för utdatabindningen filename matchas mot namnet på den utlösande bloben.

public static void CreateThumbnail(
    [BlobTrigger("sample-images/{filename}")] Stream image,
    [Blob("sample-images-sm/{filename}", FileAccess.Write)] Stream imageSmall,
    string filename,
    ILogger logger)
{
    logger.Info($"Blob trigger processing: {filename}");
    // ...
}

Mer information om bindningsuttryck finns i Bind uttryck och mönster i Azure Functions-dokumentationen.

Anpassade bindningsuttryck

Ibland vill du ange ett könamn, ett blobnamn eller en container eller ett tabellnamn i koden i stället för att hårdkoda det. Du kanske till exempel vill ange könamnet för QueueTrigger attributet i en konfigurationsfil eller miljövariabel.

Du kan göra det genom att skicka en anpassad namnmatchare under konfigurationen. Du inkluderar platshållare i utlösar- eller bindningsattributkonstruktorparametrar, och din matchningskod innehåller de faktiska värden som ska användas i stället för dessa platshållare. Du identifierar platshållare genom att omge dem med procenttecken (%) enligt följande:

public static void WriteLog([QueueTrigger("%logqueue%")] string logMessage)
{
    Console.WriteLine(logMessage);
}

Med den här koden kan du använda en kö med namnet logqueuetest i testmiljön och en med namnet logqueueprod i produktion. I stället för ett hårdkodat könamn anger du namnet på en post i appSettings samlingen.

Det finns en standardlösare som börjar gälla om du inte anger en anpassad lösning. Standardvärdet hämtar värden från appinställningar eller miljövariabler.

Från och med .NET Core 3.1 kräver du ConfigurationManager NuGet-paketet System.Configuration.ConfigurationManager. Exemplet kräver följande using instruktion:

using System.Configuration;

Klassen NameResolver hämtar könamnet från appinställningarna, som du ser här:

public class CustomNameResolver : INameResolver
{
    public string Resolve(string name)
    {
        return ConfigurationManager.AppSettings[name].ToString();
    }
}

Version 3.x

Du konfigurerar matcharen med hjälp av beroendeinmatning. Dessa exempel kräver följande using instruktion:

using Microsoft.Extensions.DependencyInjection;

Du lägger till matcharen genom att anropa ConfigureServices tilläggsmetoden på HostBuilder, som i det här exemplet:

static async Task Main(string[] args)
{
    var builder = new HostBuilder();
    var resolver = new CustomNameResolver();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
    });
    builder.ConfigureServices(s => s.AddSingleton<INameResolver>(resolver));
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Version 2.x

NameResolver Skicka klassen till objektetJobHost, som du ser här:

 static void Main(string[] args)
{
    JobHostConfiguration config = new JobHostConfiguration();
    config.NameResolver = new CustomNameResolver();
    JobHost host = new JobHost(config);
    host.RunAndBlock();
}

Azure Functions implementerar INameResolver för att hämta värden från appinställningar, som du ser i exemplet. När du använder WebJobs SDK direkt kan du skriva en anpassad implementering som hämtar platshållarersättningsvärden från vilken källa du vill.

Bindning vid körning

Om du behöver utföra lite arbete i funktionen innan du använder ett bindningsattribut som Queue, Blobeller Table, kan du använda IBinder gränssnittet.

I följande exempel visas ett indatakömeddelande och ett nytt meddelande skapas med samma innehåll i en utdatakö. Namnet på utdatakön anges efter kod i funktionens brödtext.

public static void CreateQueueMessage(
    [QueueTrigger("inputqueue")] string queueMessage,
    IBinder binder)
{
    string outputQueueName = "outputqueue" + DateTime.Now.Month.ToString();
    QueueAttribute queueAttribute = new QueueAttribute(outputQueueName);
    CloudQueue outputQueue = binder.Bind<CloudQueue>(queueAttribute);
    outputQueue.AddMessageAsync(new CloudQueueMessage(queueMessage));
}

Mer information finns i Bindning vid körning i Azure Functions-dokumentationen.

Bindningsreferensinformation

Azure Functions-dokumentationen innehåller referensinformation om varje bindningstyp. Du hittar följande information i varje bindningsreferensartikel. (Det här exemplet baseras på lagringskö.)

  • Paket. Paketet som du behöver installera för att inkludera stöd för bindningen i ett WebJobs SDK-projekt.
  • Exempel. Kodexempel. C#-klassbiblioteksexemplet gäller för WebJobs SDK. Utelämna bara attributet FunctionName .
  • Attribut. Attributen som ska användas för bindningstypen.
  • Konfiguration. Förklaringar av attributegenskaperna och konstruktorparametrarna.
  • Användning. De typer du kan binda till och information om hur bindningen fungerar. Till exempel: avsökningsalgoritm, bearbetning av giftköer.

Kommentar

HTTP-, Webhooks- och Event Grid-bindningarna stöds endast av Azure Functions, inte av WebJobs SDK.

En fullständig lista över bindningar som stöds i Azure Functions-körning finns i Bindningar som stöds.

Attribut för Inaktivera, Tidsgräns och Singleton

Med dessa attribut kan du styra funktionsutlösande, avbryta funktioner och se till att endast en instans av en funktion körs.

Inaktivera attribut

Med Disable attributet kan du styra om en funktion kan utlösas.

Om appinställningen Disable_TestJob i följande exempel har värdet 1 eller True (skiftlägesokänslig) körs inte funktionen. I så fall skapar körningen ett loggmeddelande Funktion "Functions.TestJob" är inaktiverad.

[Disable("Disable_TestJob")]
public static void TestJob([QueueTrigger("testqueue2")] string message)
{
    Console.WriteLine("Function with Disable attribute executed!");
}

När du ändrar appinställningsvärden i Azure Portal startas webbjobbet om för att hämta den nya inställningen.

Attributet kan deklareras på parameter-, metod- eller klassnivå. Inställningsnamnet kan också innehålla bindningsuttryck.

Timeout-attribut

Attributet Timeout gör att en funktion avbryts om den inte avslutas inom en angiven tid. I följande exempel skulle funktionen köras under en dag utan attributet Timeout. Timeout gör att funktionen avbryts efter 15 sekunder. När timeout-attributets parameter "throwOnError" är inställd på "true" avslutas funktionsanropet genom att ett undantag genereras av webjobs SDK när tidsgränsintervallet överskrids. Standardvärdet för "throwOnError" är "false". När attributet Timeout används är standardbeteendet att avbryta funktionsanropet genom att ange annulleringstoken samtidigt som anropet kan köras på obestämd tid tills funktionskoden returnerar eller utlöser ett undantag.

[Timeout("00:00:15")]
public static async Task TimeoutJob(
    [QueueTrigger("testqueue2")] string message,
    CancellationToken token,
    TextWriter log)
{
    await log.WriteLineAsync("Job starting");
    await Task.Delay(TimeSpan.FromDays(1), token);
    await log.WriteLineAsync("Job completed");
}

Du kan använda attributet Timeout på klass- eller metodnivå och du kan ange en global timeout med hjälp JobHostConfiguration.FunctionTimeoutav . Timeouter på klassnivå eller metodnivå åsidosätter globala timeouter.

Singleton-attribut

Attributet Singleton säkerställer att endast en instans av en funktion körs, även om det finns flera instanser av värdwebbappen. Attributet Singleton använder distribuerad låsning för att säkerställa att en instans körs.

I det här exemplet körs bara en enda instans av ProcessImage funktionen vid en viss tidpunkt:

[Singleton]
public static async Task ProcessImage([BlobTrigger("images")] Stream image)
{
     // Process the image.
}

SingletonMode.Listener

Vissa utlösare har inbyggt stöd för samtidighetshantering:

  • QueueTrigger. Ställ in JobHostConfiguration.Queues.BatchSize1.
  • ServiceBusTrigger. Ställ in ServiceBusConfiguration.MessageOptions.MaxConcurrentCalls1.
  • FileTrigger. Ställ in FileProcessor.MaxDegreeOfParallelism1.

Du kan använda de här inställningarna för att se till att funktionen körs som en singleton på en enda instans. För att säkerställa att endast en enskild instans av funktionen körs när webbappen skalar ut till flera instanser använder du ett singleton-lås på lyssnarnivå på funktionen ([Singleton(Mode = SingletonMode.Listener)]). Lyssnarlås hämtas när JobHost startar. Om tre utskalade instanser startar samtidigt, hämtar bara en av instanserna låset och endast en lyssnare startar.

Kommentar

Mer information om hur SingletonMode.Function fungerar finns i den här GitHub-lagringsplatsen .

Omfångsvärden

Du kan ange ett omfångsuttryck/värde för en singleton. Uttrycket/värdet säkerställer att alla körningar av funktionen i ett visst omfång serialiseras. Om du implementerar mer detaljerad låsning på det här sättet kan du få en viss parallellitetsnivå för din funktion samtidigt som du serialiserar andra anrop enligt dina krav. I följande kod binder till exempel omfångsuttrycket till Region värdet för det inkommande meddelandet. När kön innehåller tre meddelanden i regionerna East, East och West körs meddelandena som har region Öst seriellt. Meddelandet med regionen Väst körs parallellt med dem i regionen Öst.

[Singleton("{Region}")]
public static async Task ProcessWorkItem([QueueTrigger("workitems")] WorkItem workItem)
{
     // Process the work item.
}

public class WorkItem
{
     public int ID { get; set; }
     public string Region { get; set; }
     public int Category { get; set; }
     public string Description { get; set; }
}

SingletonScope.Host

Standardomfånget för ett lås är SingletonScope.Function, vilket innebär att låsomfånget (bloblånsökvägen) är kopplat till det fullständigt kvalificerade funktionsnamnet. Om du vill låsa över funktioner anger SingletonScope.Host och använder du ett omfångs-ID som är detsamma för alla funktioner som du inte vill köra samtidigt. I följande exempel är det bara en instans av AddItem eller RemoveItem körs i taget:

[Singleton("ItemsLock", SingletonScope.Host)]
public static void AddItem([QueueTrigger("add-item")] string message)
{
     // Perform the add operation.
}

[Singleton("ItemsLock", SingletonScope.Host)]
public static void RemoveItem([QueueTrigger("remove-item")] string message)
{
     // Perform the remove operation.
}

Visa låneblobar

WebJobs SDK använder Azure-bloblån under täcket för att implementera distribuerad låsning. De låneblobar som används av Singleton finns i containern azure-webjobs-host i AzureWebJobsStorage lagringskontot under sökvägen "lås". Till exempel kan sökvägen för lånebloben för det första ProcessImage exemplet som visades tidigare vara locks/061851c758f04938a4426aa9ab3869c0/WebJobs.Functions.ProcessImage. Alla sökvägar inkluderar JobHost-ID i det här fallet 061851c758f04938a4426aa9ab3869c0.

Async-funktioner

Information om hur du kodar asynkrona funktioner finns i Azure Functions-dokumentationen.

Annulleringstoken

Information om hur du hanterar annulleringstoken finns i Azure Functions-dokumentationen om annulleringstoken och graciös avstängning.

Flera instanser

Om webbappen körs på flera instanser körs ett kontinuerligt webbjobb på varje instans och lyssnar efter utlösare och samtalsfunktioner. De olika utlösarbindningarna är utformade för att effektivt dela samarbete mellan instanser, så att du kan hantera mer belastning genom att skala ut till fler instanser.

Vissa utlösare kan leda till dubbelbearbetning, men utlösare för kö- och bloblagring hindrar automatiskt en funktion från att bearbeta ett kömeddelande eller en blob mer än en gång. Mer information finns i Designa för identiska indata i Azure Functions-dokumentationen.

Timerutlösaren ser automatiskt till att endast en instans av timern körs, så att du inte får mer än en funktionsinstans som körs vid en viss schemalagd tidpunkt.

Om du vill se till att endast en instans av en funktion körs även när det finns flera instanser av värdwebbappen kan du använda attributet Singleton .

Filter

Funktionsfilter (förhandsversion) är ett sätt att anpassa webjobs-körningspipelinen med din egen logik. Filter liknar ASP.NET Core-filter. Du kan implementera dem som deklarativa attribut som tillämpas på dina funktioner eller klasser. Mer information finns i Funktionsfilter.

Loggning och övervakning

Vi rekommenderar det loggningsramverk som har utvecklats för ASP.NET. Artikeln Kom igång visar hur du använder den.

Loggfiltrering

Varje logg som skapas av en ILogger instans har en associerad Category och Level. LogLevel är en uppräkning och heltalskoden anger relativ betydelse:

Loggnivå Kod
Spårning 0
Felsöka 1
Information 2
Varning 3
Fel 4
Kritiskt 5
Ingen 6

Du kan filtrera varje kategori separat till en viss LogLevel. Du kanske till exempel vill se alla loggar för blobutlösarbearbetning men bara Error och högre för allt annat.

Version 3.x

Version 3.x av SDK:et förlitar sig på den inbyggda filtreringen i .NET Core. Med LogCategories klassen kan du definiera kategorier för specifika funktioner, utlösare eller användare. Den definierar även filter för specifika värdtillstånd, till exempel Startup och Results. På så sätt kan du finjustera loggningsutdata. Om ingen matchning hittas inom de definierade kategorierna återgår filtret till Default värdet när du bestämmer dig för om meddelandet ska filtreras.

LogCategories kräver följande användningsuttryck:

using Microsoft.Azure.WebJobs.Logging; 

I följande exempel skapas ett filter som som standard filtrerar alla loggar på nivån Warning . Function Kategorierna och results (motsvarar Host.Results i version 2.x) filtreras på nivånError. Filtret jämför den aktuella kategorin med alla registrerade nivåer i instansen LogCategories och väljer den längsta matchningen. Det innebär att den Debug nivå som registrerats för Host.Triggers matchningar Host.Triggers.Queue eller Host.Triggers.Blob. På så sätt kan du styra bredare kategorier utan att behöva lägga till var och en.

static async Task Main(string[] args)
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
    });
    builder.ConfigureLogging(logging =>
            {
                logging.SetMinimumLevel(LogLevel.Warning);
                logging.AddFilter("Function", LogLevel.Error);
                logging.AddFilter(LogCategories.CreateFunctionCategory("MySpecificFunctionName"),
                    LogLevel.Debug);
                logging.AddFilter(LogCategories.Results, LogLevel.Error);
                logging.AddFilter("Host.Triggers", LogLevel.Debug);
            });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

Version 2.x

I version 2.x av SDK använder LogCategoryFilter du klassen för att styra filtrering. LogCategoryFilter Har en Default egenskap med ett initialt värde på Information, vilket innebär att alla meddelanden på Informationnivåerna , Warning, Error, eller Critical loggas, men alla meddelanden på Debug nivåerna eller Trace filtreras bort.

LogCategories Precis som i version 3.x kan du med egenskapen CategoryLevels ange loggnivåer för specifika kategorier så att du kan finjustera loggningsutdata. Om ingen matchning hittas i CategoryLevels ordlistan återgår filtret till Default värdet när du bestämmer dig för om meddelandet ska filtreras.

I följande exempel skapas ett filter som som standard filtrerar alla loggar på nivån Warning . Kategorierna Function och Host.Results filtreras på Error nivån. Jämför LogCategoryFilter den aktuella kategorin med alla registrerade CategoryLevels och väljer den längsta matchningen. Så den nivå som Debug registrerats för Host.Triggers matchar Host.Triggers.Queue eller Host.Triggers.Blob. På så sätt kan du styra bredare kategorier utan att behöva lägga till var och en.

var filter = new LogCategoryFilter();
filter.DefaultLevel = LogLevel.Warning;
filter.CategoryLevels[LogCategories.Function] = LogLevel.Error;
filter.CategoryLevels[LogCategories.Results] = LogLevel.Error;
filter.CategoryLevels["Host.Triggers"] = LogLevel.Debug;

config.LoggerFactory = new LoggerFactory()
    .AddApplicationInsights(instrumentationKey, filter.Filter)
    .AddConsole(filter.Filter);

Anpassad telemetri för Application Insights

Processen för att implementera anpassad telemetri för Application Insights beror på SDK-versionen. Mer information om hur du konfigurerar Application Insights finns i Lägga till Application Insights-loggning.

Version 3.x

Eftersom version 3.x av WebJobs SDK förlitar sig på den allmänna .NET Core-värden. En anpassad telemetrifabrik tillhandahålls inte längre. Men du kan lägga till anpassad telemetri i pipelinen med hjälp av beroendeinmatning. Exemplen i det här avsnittet kräver följande using instruktioner:

using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Channel;

Med följande anpassade implementering av ITelemetryInitializer kan du lägga till din egen ITelemetry i standardinställningen TelemetryConfiguration.

internal class CustomTelemetryInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        // Do something with telemetry.
    }
}

Anropa ConfigureServices byggverktyget för att lägga till din anpassade ITelemetryInitializer i pipelinen.

static async Task Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
    });
    builder.ConfigureLogging((context, b) =>
    {
        // Add logging providers.
        b.AddConsole();

        // If this key exists in any config, use it to enable Application Insights.
        string appInsightsKey = context.Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
        if (!string.IsNullOrEmpty(appInsightsKey))
        {
            // This uses the options callback to explicitly set the instrumentation key.
            b.AddApplicationInsights(o => o.InstrumentationKey = appInsightsKey);
        }
    });
    builder.ConfigureServices(services =>
        {
            services.AddSingleton<ITelemetryInitializer, CustomTelemetryInitializer>();
        });
    var host = builder.Build();
    using (host)
    {
        await host.RunAsync();
    }
}

När är TelemetryConfiguration konstruerad inkluderas alla registrerade typer av ITelemetryInitializer . Mer information finns i Application Insights API för anpassade händelser och mått.

I version 3.x behöver du inte längre tömma TelemetryClient när värden stoppas. .NET Core-beroendeinmatningssystemet gör sig automatiskt av med den registrerade ApplicationInsightsLoggerProvider, som rensar TelemetryClient.

Version 2.x

I version 2.x, den TelemetryClient som skapats internt av Application Insights-providern för WebJobs SDK använder ServerTelemetryChannel. När Application Insights-slutpunkten inte är tillgänglig eller begränsar inkommande begäranden sparar den här kanalen begäranden i webbappens filsystem och skicka dem igen senare.

TelemetryClient Skapas av en klass som implementerar ITelemetryClientFactory. Som standard är DefaultTelemetryClientFactorydetta .

Om du vill ändra någon del av Application Insights-pipelinen kan du ange din egen ITelemetryClientFactory, och värden använder klassen för att konstruera en TelemetryClient. Den här koden åsidosätter DefaultTelemetryClientFactory till exempel för att ändra en egenskap för ServerTelemetryChannel:

private class CustomTelemetryClientFactory : DefaultTelemetryClientFactory
{
    public CustomTelemetryClientFactory(string instrumentationKey, Func<string, LogLevel, bool> filter)
        : base(instrumentationKey, new SamplingPercentageEstimatorSettings(), filter)
    {
    }

    protected override ITelemetryChannel CreateTelemetryChannel()
    {
        ServerTelemetryChannel channel = new ServerTelemetryChannel();

        // Change the default from 30 seconds to 15 seconds.
        channel.MaxTelemetryBufferDelay = TimeSpan.FromSeconds(15);

        return channel;
    }
}

Objektet SamplingPercentageEstimatorSettings konfigurerar anpassningsbar sampling. Det innebär att i vissa scenarier med stora volymer skickar Applications Insights en vald delmängd av telemetridata till servern.

När du har skapat telemetrifabriken skickar du den till Application Insights-loggningsprovidern:

var clientFactory = new CustomTelemetryClientFactory(instrumentationKey, filter.Filter);

config.LoggerFactory = new LoggerFactory()
    .AddApplicationInsights(clientFactory);

Nästa steg

Den här artikeln innehåller kodfragment som visar hur du hanterar vanliga scenarier för att arbeta med WebJobs SDK. Fullständiga exempel finns i azure-webjobs-sdk-samples.