Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este artigo descreve como trabalhar com o SDK do Azure WebJobs. Para começar rapidamente a usar WebJobs, consulte Introdução ao SDK do Azure WebJobs.
Versões do SDK de WebJobs
As principais diferenças entre a versão 3. x e versão 2. x do SDK WebJobs são:
- Versão 3.x adiciona suporte para .NET Core.
- Na versão 3. x, você instala a extensão de vinculação de armazenamento exigida pelo SDK WebJobs. Na versão 2.x, as associações de armazenamento estão incluídas no SDK.
- Ferramentas do Visual Studio 2019 para os projetos .NET Core (3.x) diferem das ferramentas para os projetos .NET Framework (2.x). Para obter mais informações, consulte Desenvolver e implantar WebJobs usando o Visual Studio.
Alguns exemplos neste artigo são fornecidos para ambos WebJobs versão 3. x e WebJobs versão 2. x.
O Azure Functions baseia-se no SDK de WebJobs:
- Azure Functions versão 2.x é construído em WebJobs SDK versão 3.x.
- Azure Functions versão 1.x é baseado em WebJobs SDK versão 2.x.
Os repositórios de código-fonte para o Azure Functions e o SDK WebJobs usam a numeração do SDK WebJobs. Várias seções deste artigo estão vinculadas à documentação do Azure Functions.
Para obter mais informações, consulte Comparar o SDK de WebJobs e o Azure Functions.
Anfitrião WebJobs
O host WebJobs é um contêiner de tempo de execução para funções. O host escuta as funções de gatilhos e chamadas. Na versão 3.x, o host é uma implementação do IHost
. Na versão 2.x, você usa o JobHost
objeto. Você cria uma instância de host em seu código e escreve código para personalizar seu comportamento.
Essa alteração de arquitetura é uma diferença fundamental entre usar o SDK de WebJobs diretamente e usá-lo indiretamente por meio do Azure Functions. No Azure Functions, o serviço controla o host. Não é possível personalizar o host escrevendo código. Nas Azure Functions, você personaliza o comportamento do host por meio de definições no arquivo host.json
. Essas configurações são strings, não código, e o uso dessas strings limita os tipos de personalizações que você pode fazer.
Conexões de host
O SDK do WebJobs procura conexões do Armazenamento do Azure e do Barramento de Serviço do Azure no ficheiro local.settings.json
quando se executa localmente ou no ambiente do WebJob quando executado no Azure. Por padrão, o SDK WebJobs requer uma conexão de armazenamento chamada AzureWebJobsStorage
.
Quando o nome da conexão se resolve a um único valor exato, o runtime identifica o valor como uma string de conexão, que normalmente inclui um segredo. Os detalhes de uma cadeia de conexão dependem do serviço ao qual você se conecta. No entanto, um nome de conexão também pode se referir a uma coleção de vários itens de configuração. Esse método é útil para configurar conexões baseadas em identidade. Você pode tratar variáveis de ambiente como uma coleção usando um prefixo compartilhado que termina em sublinhados duplos (__
). Em seguida, você pode fazer referência ao grupo definindo o nome da conexão para esse prefixo.
Por exemplo, a propriedade para a definição de um gatilho de Armazenamento de Blobs do Azure connection
pode ser Storage1
. Contanto que não haja um único valor de cadeia de caracteres configurado por uma variável de ambiente chamada Storage1
, uma variável de ambiente nomeada Storage1__blobServiceUri
pode ser usada para informar a blobServiceUri
propriedade da conexão. As propriedades de conexão são diferentes para cada serviço. Consulte a documentação do componente que usa a conexão.
Conexões baseadas em identidade
Para usar conexões baseadas em identidade no SDK WebJobs, certifique-se de usar as versões mais recentes dos pacotes WebJobs em seu projeto. Certifique-se também de que tem uma referência a Microsoft.Azure.WebJobs.Host.Storage.
O exemplo a seguir mostra a aparência do arquivo de projeto depois de fazer essas atualizações:
<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.42" />
<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>
Ao configurar WebJobs em sua instância do HostBuilder, certifique-se de incluir uma chamada para AddAzureStorageCoreServices
. Essa chamada permite que AzureWebJobsStorage
e outros gatilhos e ligações de armazenamento usem a identidade.
Aqui está um exemplo:
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
// Other configurations...
});
Em seguida, você pode configurar a conexão definindo variáveis de AzureWebJobsStorage
ambiente (ou configurações de aplicativo quando seu código é hospedado no Serviço de Aplicativo do Azure):
Variável de ambiente | Descrição | Valor de exemplo |
---|---|---|
AzureWebJobsStorage__blobServiceUri |
O URI do plano de dados do serviço de blob da conta de armazenamento. Ele usa o esquema HTTPS. | https://< storage_account_name.blob.core.windows.net> |
AzureWebJobsStorage__queueServiceUri |
O URI do plano de dados do serviço de fila da conta de armazenamento. Ele usa o esquema HTTPS. | https://< storage_account_name.queue.core.windows.net> |
Se você fornecer sua configuração por qualquer meio que não seja variáveis de ambiente, como em um appsettings.json
arquivo de configuração, deverá fornecer uma configuração estruturada para a conexão e suas propriedades:
{
"AzureWebJobsStorage": {
"blobServiceUri": "https://<storage_account_name>.blob.core.windows.net",
"queueServiceUri": "https://<storage_account_name>.queue.core.windows.net"
}
}
Você pode omitir a propriedade queueServiceUri
se não planeia usar gatilhos de blobs.
Quando o código é executado localmente, o padrão é usar a identidade do desenvolvedor conforme descrito para DefaultAzureCredential
.
Quando seu código é hospedado no Serviço de Aplicativo, a configuração no exemplo anterior assume como padrão a identidade gerenciada atribuída pelo sistema para o recurso. Para usar uma identidade atribuída ao usuário atribuída ao aplicativo, você deve adicionar propriedades para sua conexão para especificar qual identidade usar. A credential
propriedade (AzureWebJobsStorage__credential
como uma variável de ambiente) deve ser definida como a cadeia de caracteres managedidentity
. A clientId
propriedade (AzureWebJobsStorage__clientId
como uma variável de ambiente) deve ser definida como a ID do cliente da identidade gerenciada atribuída pelo usuário a ser usada.
Como uma configuração estruturada, o objeto completo seria semelhante a este exemplo:
{
"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>"
}
}
A identidade usada para AzureWebJobsStorage
deve ter atribuições de função que lhe concedam as funções de Proprietário de Dados de Blob de Armazenamento, Colaborador de Dados da Fila de Armazenamento e Colaborador de Conta de Armazenamento . Você pode omitir as funções Colaborador de Dados da Fila de Armazenamento e Colaborador da Conta de Armazenamento se não planeja usar gatilhos de blob.
A tabela a seguir mostra funções incorporadas que recomendamos quando se usam gatilhos em associações em operação normal. Seu aplicativo pode exigir mais permissões, dependendo do código que você escreve.
Encadernação | Exemplo de funções internas |
---|---|
gatilho de blob |
Proprietário dos Dados de Armazenamento Blob eContribuidor dos Dados de Fila de Armazenamento Consulte também os requisitos anteriores para AzureWebJobsStorage . |
Blob (entrada) | Leitor de Dados do Armazenamento de Blobs |
Blob (saída) | Proprietário de Dados do Armazenamento Blob |
Disparador de fila | Leitor de dados da fila de armazenamento, processador de mensagens de dados da fila de armazenamento |
Fila (saída) | Contribuinte de dados da fila de armazenamento, Remetedor de mensagem de dados da fila de armazenamento |
Gatilho do Service Bus1 | Recetor de Dados do Barramento de Serviço do Azure, Proprietário de Dados do Barramento de Serviço do Azure |
Service Bus (saída) | Remetente de dados do Azure Service Bus |
1 Para acionar a partir de tópicos do Service Bus, a atribuição de função deve ter escopo efetivo sobre o recurso de assinatura do Service Bus. Se apenas o tópico for incluído, ocorrerá um erro. Alguns clientes, como o portal do Azure, não expõem o recurso de subscrição do Service Bus como um âmbito para atribuição de função. Nesses cenários, você pode usar a CLI do Azure. Para obter mais informações, consulte Funções internas do Azure para o Barramento de Serviço do Azure.
Cadeias de conexão na versão 2. x
Versão 2. x do SDK não requer um nome específico para cadeias de conexão. Na versão 2. x, você pode usar seus próprios nomes para essas cadeias de conexão e armazená-las em outro lugar. Você pode definir nomes no código usando JobHostConfiguration
, como neste exemplo:
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();
}
Nota
Porque a versão 3. x usa as APIs de configuração padrão do .NET Core, nenhuma API existe para alterar nomes de cadeia de conexão. Para obter mais informações, consulte Desenvolver e implantar WebJobs usando o Visual Studio.
Configurações de desenvolvimento do host
Você pode executar o host no modo de desenvolvimento para tornar o desenvolvimento local mais eficiente. Aqui estão algumas das configurações que mudam automaticamente quando você executa no modo de desenvolvimento:
Propriedade | Configuração de desenvolvimento |
---|---|
Tracing.ConsoleLevel |
TraceLevel.Verbose para maximizar a saída do log. |
Queues.MaxPollingInterval |
Um valor baixo para garantir que os métodos de fila sejam acionados imediatamente. |
Singleton.ListenerLockPeriod |
15 segundos para ajudar com o rápido desenvolvimento iterativo. |
O processo para habilitar o modo de desenvolvimento depende da versão do SDK.
Versão 3.x
Na versão 3. x, você usa as APIs padrão do ASP.NET Core para alterar o ambiente do host. Chame o método UseEnvironment
na instância HostBuilder
. Passe uma cadeia de caracteres chamada development
, como neste exemplo:
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();
}
}
Versão 2.x
A JobHostConfiguration
classe tem um método que permite o UseDevelopmentSettings
modo de desenvolvimento. O exemplo a seguir mostra como usar as configurações de desenvolvimento. Para retornar config.IsDevelopment
true
quando ele for executado localmente, defina uma variável de ambiente local chamada AzureWebJobsEnv
que tenha o valor Development
.
static void Main()
{
config = new JobHostConfiguration();
if (config.IsDevelopment)
{
config.UseDevelopmentSettings();
}
var host = new JobHost(config);
host.RunAndBlock();
}
Gerenciar conexões simultâneas (versão 2.x)
Na versão 3.x, o limite de conexão padrão é definido para conexões infinitas. Se, por algum motivo, tu precisares alterar este limite, podes usar a propriedade MaxConnectionsPerServer
da classe WinHttpHandler
.
Na versão 2. x, você controla o número de conexões simultâneas com um host usando a ServicePointManager.DefaultConnectionLimit
propriedade. Em 2.x, você deve aumentar esse valor a partir do valor padrão antes de iniciar o seu host do WebJobs 2
.
Todas as solicitações HTTP de saída que faz a partir de uma função utilizando HttpClient
passam através do ServicePointManager
. Depois de atingir o valor definido em DefaultConnectionLimit
, ServicePointManager
começa a enfileirar solicitações antes de enviá-las. Suponha que o teu DefaultConnectionLimit
esteja definido como 2
e o teu código faça 1.000 pedidos HTTP. Inicialmente, apenas 2 solicitações são permitidas através do sistema operacional. Os outros 998 pedidos estão na fila até que haja espaço para eles. O seu HttpClient
pode expirar porque parece ter efetuado a solicitação, mas a solicitação nunca foi enviada pelo sistema operativo até ao servidor de destino. Você pode ver um comportamento que não parece fazer sentido: seu local HttpClient
está levando 10 segundos para concluir uma solicitação, mas seu serviço está retornando todas as solicitações em 200 ms.
O valor padrão para aplicativos ASP.NET é Int32.MaxValue
, e é provável que funcione bem para WebJobs em execução em um plano de Serviço de Aplicativo Básico ou superior. Os WebJobs normalmente precisam da configuração Always On, e isso é suportado apenas pelos planos Basic e superiores do Serviço de Aplicações.
Se o WebJob estiver sendo executado em um plano do Serviço de Aplicativo Gratuito ou Compartilhado, seu aplicativo será restrito pela área restrita do Serviço de Aplicativo, que atualmente tem um limite de conexão de 600. Se tiver um limite de conexão ilimitado no ServicePointManager
, há uma maior probabilidade de que o limite de conexão da sandbox seja atingido e o site seja encerrado. Nesse caso, a configuração DefaultConnectionLimit
para algo mais baixo, como 200, pode impedir que esse cenário ocorra e ainda permitir uma taxa de transferência suficiente.
A configuração deve ser configurada antes que qualquer solicitação HTTP seja feita. Por esse motivo, o host WebJobs não deve ajustar a configuração automaticamente. Pode haver solicitações HTTP que ocorrem antes do host iniciar, o que pode levar a um comportamento inesperado. A melhor abordagem é definir o valor imediatamente em seu Main
método antes de inicializar JobHost
, como mostrado neste exemplo:
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();
}
Acionadores
O SDK WebJobs dá suporte ao mesmo conjunto de gatilhos e vinculação que o Azure Functions usa. No SDK WebJobs, os gatilhos são específicos da função e não estão relacionados ao tipo de implantação WebJob. WebJobs que têm funções acionadas por eventos criadas usando o SDK devem sempre ser publicados como um WebJob contínuo , com Always on habilitado.
As funções devem ser métodos públicos e devem ter um atributo trigger ou o NoAutomaticTrigger
atributo.
Gatilhos automáticos
Os gatilhos automáticos chamam uma função em resposta a um evento. Considere este exemplo de uma função acionada por uma mensagem adicionada ao Armazenamento de Filas do Azure. A função responde lendo um blob do armazenamento de blobs.
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");
}
O atributo QueueTrigger
indica ao tempo de execução para chamar a função sempre que uma mensagem de fila aparecer em myqueue-items
. O atributo Blob
informa o tempo de execução para utilizar a mensagem de fila a fim de ler um blob no contentor sample-workitems
. O nome do item de blob no samples-workitems
contêiner é obtido diretamente do gatilho de fila como uma expressão de ligação ({queueTrigger}
).
Nota
Um aplicativo Web pode atingir o tempo limite após 20 minutos de inatividade, e somente solicitações para o aplicativo Web real podem redefinir o temporizador. Exibir a configuração do aplicativo no portal do Azure ou fazer solicitações para o site de ferramentas avançadas não redefine o temporizador. Se você definir o aplicativo Web que hospeda seu trabalho para ser executado continuamente, executado em uma agenda ou usar gatilhos controlados por eventos, habilite a configuração Sempre ativado no painel Configuração do Azure do seu aplicativo Web. A configuração Sempre ligado ajuda a garantir que esses tipos de WebJobs sejam executados de forma confiável. Esse recurso está disponível apenas nos níveis de preços Basic, Standard e Premium.
Gatilhos manuais
Para acionar uma função manualmente, use o atributo NoAutomaticTrigger
:
[NoAutomaticTrigger]
public static void CreateQueueMessage(
ILogger logger,
string value,
[Queue("outputqueue")] out string message)
{
message = value;
logger.LogInformation("Creating queue message: ", message);
}
O processo para acionar manualmente a função depende da versão do SDK.
Versão 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();
}
}
Versão 2.x
static void Main(string[] args)
{
JobHost host = new JobHost();
host.Call(typeof(Program).GetMethod("CreateQueueMessage"), new { value = "Hello world!" });
}
Ligações de entrada e saída
As associações de entrada fornecem uma maneira declarativa de disponibilizar dados do Azure ou de serviços de terceiros para seu código. As ligações de saída fornecem uma maneira de atualizar dados. O artigo Introdução mostra um exemplo de cada um.
Você pode usar um valor de retorno de método para uma associação de saída aplicando o atributo ao valor de retorno do método. Veja o exemplo em Usando o valor de retorno da Função do Azure.
Tipos de vinculação
O processo de instalação e gerenciamento de tipos de vinculação depende se você está usando a versão 3.x ou versão 2.x do SDK. Você pode encontrar o pacote a ser instalado para um tipo de vinculação específico na seção "Pacotes" do artigo de referência do Azure Functions desse tipo de vinculação. Uma exceção é o gatilho e a vinculação de Arquivos (para o sistema de arquivos local), que o Azure Functions não suporta.
Versão 3.x
Na versão 3.x, as ligações de armazenamento estão incluídas no Microsoft.Azure.WebJobs.Extensions.Storage
pacote. Chame o método de extensão AddAzureStorage
no método ConfigureWebJobs
.
static async Task Main()
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddAzureStorage();
});
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
Para usar outros tipos de gatilho e ligação, instale o pacote NuGet que os contém e chame o Add<binding>
método de extensão implementado na extensão. Por exemplo, se você quiser usar uma associação do Azure Cosmos DB, instale Microsoft.Azure.WebJobs.Extensions.CosmosDB
e chame AddCosmosDB
:
static async Task Main()
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddCosmosDB();
});
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
Para usar o gatilho de Timer ou a associação de arquivos, que fazem parte dos serviços principais, chame os métodos de extensão AddTimers
ou AddFiles
.
Versão 2.x
Esses tipos de gatilho e vinculação estão incluídos na versão 2.x do pacote Microsoft.Azure.WebJobs
.
- Armazenamento de Blobs
- Armazenamento de filas
- Armazenamento de tabelas
Para usar outros tipos de gatilho e ligação, instale o pacote NuGet que os contém e chame um método Use<binding>
no objeto JobHostConfiguration
. Por exemplo, se quiseres usar um gatilho de Timer, instala Microsoft.Azure.WebJobs.Extensions
e chama UseTimers
no método Main
:
static void Main()
{
config = new JobHostConfiguration();
config.UseTimers();
var host = new JobHost(config);
host.RunAndBlock();
}
Para usar a ligação Arquivos, instale Microsoft.Azure.WebJobs.Extensions
e chame UseFiles
.
Contexto de Execução
Em WebJobs, você pode vincular a uma ExecutionContext
instância. Com essa ligação, você pode acessar ExecutionContext
como um parâmetro em sua assinatura de função. Por exemplo, o código a seguir usa o objeto de contexto para acessar a ID de invocação, que você pode usar para correlacionar todos os logs produzidos por uma determinada chamada de função.
public class Functions
{
public static void ProcessQueueMessage([QueueTrigger("queue")] string message,
ExecutionContext executionContext,
ILogger logger)
{
logger.LogInformation($"{message}\n{executionContext.InvocationId}");
}
}
O processo de vinculação a ExecutionContext
depende da sua versão do SDK.
Versão 3.x
Chame o método de extensão AddExecutionContextBinding
no método ConfigureWebJobs
.
static async Task Main()
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddExecutionContextBinding();
});
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
Versão 2.x
O Microsoft.Azure.WebJobs.Extensions
pacote mencionado anteriormente também fornece um tipo de vinculação especial que você pode registrar chamando o UseCore
método. Você pode usar a associação para definir um ExecutionContext
parâmetro em sua assinatura de função:
class Program
{
static void Main()
{
config = new JobHostConfiguration();
config.UseCore();
var host = new JobHost(config);
host.RunAndBlock();
}
}
Configuração de vinculação
Você pode configurar o comportamento de alguns gatilhos e associações. O processo para configurá-los depende da versão do SDK.
-
Versão 3.x: Defina a configuração quando o método
Add<Binding>
for chamado emConfigureWebJobs
. -
Versão 2.x: Defina a configuração definindo propriedades num objeto de configuração para o qual você passa para
JobHost
.
Essas configurações específicas de associação são equivalentes às configurações no ficheiro dehost.json
projeto nas Azure Functions.
Você pode configurar as seguintes associações:
- Gatilho do Azure Cosmos DB
- gatilho do Event Hubs
- Gatilho de armazenamento de fila
- Vinculação SendGrid
- Gatilho do Service Bus
Configuração de gatilho do Azure Cosmos DB (versão 3.x)
Este exemplo mostra como configurar o gatilho do Azure Cosmos DB:
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();
}
}
Para obter mais informações, consulte Vinculação do Azure Cosmos DB.
Configuração de gatilho dos Hubs de Eventos do Azure (versão 3.x)
Este exemplo mostra como configurar o trigger do Event Hubs:
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();
}
}
Para obter mais informações, consulte Vinculação de Hubs de Eventos.
Configuração do gatilho para armazenamento em fila
Os exemplos a seguir mostram como configurar o gatilho de armazenamento de fila.
Versão 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();
}
}
Para obter mais informações, consulte Vinculação de armazenamento em fila.
Versão 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();
}
Para obter mais informações, consulte a host.json
referência v1.x.
Configuração de vinculação do SendGrid (versão 3.x)
Este exemplo mostra como configurar a ligação de saída SendGrid:
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();
}
}
Para obter mais informações, consulte SendGrid
vinculação.
Configuração de gatilho do Service Bus (versão 3.x)
Este exemplo mostra como configurar o gatilho do Service Bus:
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();
}
}
Para obter mais informações, consulte Vinculação do Service Bus.
Configuração para outras ligações
Alguns tipos de gatilho e associação definem seus próprios tipos de configuração personalizada. Por exemplo, você pode usar o gatilho File para especificar o caminho raiz a ser monitorado, como nos exemplos a seguir.
Versão 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();
}
}
Versão 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();
}
Expressões de enlace
Em parâmetros do construtor de atributos, você pode usar expressões que resolvem para valores de várias fontes. Por exemplo, no código a seguir, o caminho para o BlobTrigger
atributo cria uma expressão chamada filename
. Quando usado para a ligação de saída, filename
resolve para o nome do blob de acionamento.
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}");
// ...
}
Para obter mais informações sobre expressões de associação, consulte Vinculando expressões e padrões na documentação do Azure Functions.
Expressões de vinculação personalizadas
Às vezes, você deseja especificar um nome de fila, um nome de blob ou contêiner ou um nome de tabela no código em vez de codificá-lo. Por exemplo, talvez você queira especificar o nome da fila para o QueueTrigger
atributo em um arquivo de configuração ou variável de ambiente.
Você pode atribuir um nome de fila ao atributo passando um resolvedor de nome personalizado durante a configuração. Você inclui espaços reservados em parâmetros do construtor de atributos de gatilho ou vinculação, e seu código de resolvedor fornece os valores reais a serem usados no lugar desses espaços reservados. Você identifica espaços reservados cercando-os com sinais de porcentagem (%
):
public static void WriteLog([QueueTrigger("%logqueue%")] string logMessage)
{
Console.WriteLine(logMessage);
}
Neste código, você usa uma fila nomeada logqueuetest
no ambiente de teste e uma fila nomeada logqueueprod
na produção. Em vez de um nome de fila codificado, especifique o nome de uma entrada na appSettings
coleção.
Um resolvedor padrão entra em vigor se você não fornecer um personalizado. O padrão obtém valores de configurações de aplicativo ou variáveis de ambiente.
A partir do .NET Core 3.1, a ConfigurationManager
instância usada requer o System.Configuration.ConfigurationManager
pacote NuGet. O exemplo requer a seguinte using
instrução:
using System.Configuration;
Sua NameResolver
classe obtém o nome da fila nas configurações do aplicativo:
public class CustomNameResolver : INameResolver
{
public string Resolve(string name)
{
return ConfigurationManager.AppSettings[name].ToString();
}
}
Versão 3.x
Para configurar o resolvedor, utilize a injeção de dependência. Esses exemplos exigem a seguinte using
instrução:
using Microsoft.Extensions.DependencyInjection;
Você adiciona o resolvedor chamando o ConfigureServices
método de extensão no HostBuilder
, como neste exemplo:
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();
}
}
Versão 2.x
Passe sua NameResolver
classe para o JobHost
objeto:
static void Main(string[] args)
{
JobHostConfiguration config = new JobHostConfiguration();
config.NameResolver = new CustomNameResolver();
JobHost host = new JobHost(config);
host.RunAndBlock();
}
O Azure Functions implementa INameResolver
para obter valores das configurações do aplicativo, conforme mostrado no exemplo. Ao usar diretamente o SDK WebJobs, pode-se escrever uma implementação personalizada que obtenha valores de substituição para espaços reservados a partir de qualquer fonte da sua preferência.
Vinculação em tempo de execução
Se você precisar fazer algum trabalho em sua função antes de usar um atributo de vinculação como Queue
, Blob
ou Table
, você pode usar a IBinder
interface.
O exemplo a seguir pega uma mensagem de fila de entrada e cria uma nova mensagem que tem o mesmo conteúdo em uma fila de saída. O nome da fila de saída é definido por código no corpo da função.
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));
}
Para obter mais informações, consulte Vinculação em tempo de execução na documentação do Azure Functions.
Informações de referência vinculativas
A documentação do Azure Functions fornece informações de referência sobre cada tipo de associação. As seguintes informações estão em cada artigo de referência vinculativa. (Este exemplo é baseado em uma fila de armazenamento.)
- Embalagens. O pacote que você precisa instalar para incluir suporte para a associação em um projeto SDK WebJobs.
-
Exemplos. Exemplos de código. O exemplo de biblioteca de classes C# se aplica ao SDK WebJobs. Basta omitir o atributo
FunctionName
. - Atributos. Os atributos a serem usados para o tipo de vinculação.
- Configuração. Explicações das propriedades do atributo e parâmetros do construtor.
- Utilização. Os tipos aos quais você pode vincular e informações sobre como a associação funciona. Por exemplo, um algoritmo de sondagem ou processamento de fila de veneno.
Nota
As ligações HTTP, Webhooks e Grade de Eventos são suportadas apenas pelo Azure Functions, não pelo SDK WebJobs.
Para obter uma lista completa das associações suportadas no tempo de execução do Azure Functions, consulte Associações suportadas.
Atributos: Desativar, Tempo Limite e Singleton
Você pode usar esses atributos para controlar o acionamento de funções, cancelar funções e garantir que apenas uma instância de uma função seja executada.
Desativar atributo
Use o Disable
atributo para controlar se uma função pode ser acionada.
No exemplo a seguir, se a configuração Disable_TestJob
do aplicativo tiver um valor de ou 1
(não específico a maiúsculas e True
minúsculas), a função não será executada. Nesse cenário, o tempo de execução cria a mensagem de log Função 'Functions.TestJob' está desabilitada.
[Disable("Disable_TestJob")]
public static void TestJob([QueueTrigger("testqueue2")] string message)
{
Console.WriteLine("Function with Disable attribute executed!");
}
Quando você altera os valores de configuração do aplicativo no portal do Azure, o WebJob é reiniciado para pegar a nova configuração.
O atributo pode ser declarado no nível do parâmetro, método ou classe. O nome da configuração também pode conter expressões de ligação.
Atributo Tempo limite
O Timeout
atributo faz com que uma função seja cancelada se ela não for concluída dentro de um período de tempo especificado. No exemplo a seguir, a função seria executada por um dia sem o Timeout
atributo. O tempo limite faz com que a função seja cancelada após 15 segundos. Quando o atributo Timeout
parâmetro throwOnError
é definido como true
, a invocação da função é encerrada, e uma exceção é lançada pelo SDK WebJobs quando o intervalo de tempo limite é excedido. O valor padrão de throwOnError
é false
. Quando o Timeout
atributo é usado, o comportamento padrão é cancelar a invocação da função definindo o token de cancelamento enquanto permite que a invocação seja executada indefinidamente até que o código da função retorne ou lance uma exceção.
[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");
}
Você pode aplicar o Timeout
atributo no nível da classe ou no nível do método e pode especificar um tempo limite global usando JobHostConfiguration.FunctionTimeout
. Os tempos limite de nível de classe ou de método substituem os tempos limite globais.
Atributo Singleton
O Singleton
atributo garante que apenas uma instância de uma função seja executada, mesmo quando há várias instâncias do aplicativo Web host. O Singleton
atributo usa bloqueio distribuído para garantir que apenas uma instância seja executada.
Neste exemplo, apenas uma única instância da função é executada ProcessImage
a qualquer momento:
[Singleton]
public static async Task ProcessImage([BlobTrigger("images")] Stream image)
{
// Process the image.
}
SingletonMode.Listener
Alguns gatilhos têm suporte interno para gerenciamento de simultaneidade:
-
QueueTrigger. Defina
JobHostConfiguration.Queues.BatchSize
como1
. -
ServiceBusTrigger. Defina
ServiceBusConfiguration.MessageOptions.MaxConcurrentCalls
como1
. -
FileTrigger. Defina
FileProcessor.MaxDegreeOfParallelism
como1
.
Você pode usar essas configurações para garantir que sua função seja executada como um singleton em uma única instância. Para garantir que apenas uma única instância da função esteja em execução quando o aplicativo Web for expandido para várias instâncias, aplique um bloqueio singleton no nível do ouvinte na função ([Singleton(Mode = SingletonMode.Listener)]
). Os bloqueios de ouvinte são adquiridos quando o JobHost é iniciado. Se três instâncias dimensionadas forem iniciadas ao mesmo tempo, apenas uma das instâncias adquirirá o bloqueio e apenas um ouvinte será iniciado.
Nota
Para saber mais sobre como SingletonMode.Function
funciona, consulte o repositório GitHub SingletonMode.
Valores de escopo
Você pode especificar uma expressão/valor de escopo em um singleton. A expressão/valor garante que todas as execuções da função em um escopo específico sejam serializadas. Implementar um bloqueio mais granular dessa maneira pode permitir algum nível de paralelismo para sua função enquanto serializa outras invocações conforme ditado por seus requisitos. Por exemplo, no código a seguir, a expressão de escopo se liga ao Region
valor da mensagem de entrada. Quando a fila contém três mensagens nas regiões Leste, Leste e Oeste, as mensagens com região Leste são executadas sequencialmente. A mensagem com a região Oeste corre em paralelo com as mensagens na região Leste.
[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
O escopo padrão para um bloqueio é SingletonScope.Function
. O escopo de bloqueio (o caminho de concessão de blob) está vinculado ao nome da função totalmente qualificada. Para bloquear entre funções, especifique SingletonScope.Host
e use um nome de ID de escopo que seja o mesmo em todas as funções que você não deseja executar simultaneamente. No exemplo a seguir, apenas uma instância de AddItem
ou RemoveItem
é executada de cada vez:
[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.
}
Visualizando blobs de leasing
O SDK de WebJobs usa concessões de blob do Azure para implementar o bloqueio distribuído. Os blobs de arrendamento usados por Singleton
podem ser encontrados no azure-webjobs-host
contentor na AzureWebJobsStorage
conta de armazenamento sob o caminho "locks". Por exemplo, o caminho do blob de arrendamento para o primeiro ProcessImage
exemplo mostrado anteriormente pode ser locks/061851c758f04938a4426aa9ab3869c0/WebJobs.Functions.ProcessImage
. Todos os caminhos incluem o ID JobHost, neste caso 061851c758f04938a4426aa9ab3869c0.
Funções assíncronas
Para obter informações sobre como codificar funções assíncronas, consulte a documentação do Azure Functions.
Tokens de cancelamento
Para obter informações sobre como lidar com tokens de cancelamento, consulte a documentação do Azure Functions sobre tokens de cancelamento e encerramento gracioso.
Múltiplas instâncias
Se a sua aplicação web estiver a funcionar em várias instâncias, um WebJob contínuo será executado em cada instância, à escuta de gatilhos e chamando funções. As várias ligações de acionadores são projetadas para compartilhar eficientemente o trabalho de forma colaborativa entre instâncias, permitindo que a escalabilidade para mais instâncias possibilite o manuseio de maior carga.
Embora alguns gatilhos possam resultar em processamento duplo, os gatilhos relacionados ao armazenamento de fila e blob impedem automaticamente que uma função processe uma mensagem de fila ou um blob mais de uma vez. Para obter mais informações, consulte Projetando para entrada idêntica na documentação do Azure Functions.
O gatilho do temporizador garante automaticamente que apenas uma instância do temporizador seja executada, para que você não tenha mais de uma instância de função em execução em um determinado horário agendado.
Se quiser garantir que apenas uma instância de uma função seja executada, mesmo quando houver várias instâncias do aplicativo Web host, você poderá usar o Singleton
atributo.
Filtros
Os Filtros de Funções (pré-visualização) fornecem uma maneira de personalizar o pipeline de execução dos WebJobs usando a sua própria lógica. Esses filtros são semelhantes aos filtros ASP.NET Core. Você pode implementá-los como atributos declarativos que são aplicados às suas funções ou classes. Para obter mais informações, consulte Filtros de função.
Registos e monitorização
Recomendamos que você use a estrutura de log que foi desenvolvida para ASP.NET. O artigo Introdução mostra como usá-lo.
Filtragem de logs
Cada log criado por uma ILogger
instância tem valores e associados Category
Level
.
LogLevel
é uma enumeração e o código inteiro indica importância relativa:
Nível de Log | Código |
---|---|
Rastreio | 0 |
Depurar | 1 |
Informação | 2 |
Aviso | 3 |
Erro | 4 |
Crítico | 5 |
Nenhuma | 6 |
Você pode filtrar independentemente cada categoria para um valor específico LogLevel
. Por exemplo, talvez queiras ver todos os registos de processamento de ativação de blob, mas apenas Error
ou níveis superiores para todo o resto.
Versão 3.x
Versão 3. x do SDK depende da filtragem incorporada no .NET Core. Use a LogCategories
classe para definir categorias para funções, gatilhos ou usuários específicos. A LogCategories
classe também define filtros para estados de host específicos, como Startup
e Results
, para que você possa ajustar a saída de log. Se nenhuma correspondência for encontrada nas categorias definidas, o filtro retornará ao Default
valor ao determinar se a mensagem deve ser filtrada.
LogCategories
requer a seguinte using
declaração:
using Microsoft.Azure.WebJobs.Logging;
O exemplo a seguir constrói um filtro que, por padrão, filtra todos os Warning
logs no nível. As Function
e results
categorias (equivalentes a Host.Results
na versão 2.x) são filtradas ao nível Error
. O filtro compara a categoria atual com todos os níveis registrados na LogCategories
instância e escolhe a correspondência mais longa. Assim, o nível registado para Debug
corresponder a Host.Triggers
ou Host.Triggers.Queue
. Você pode controlar categorias mais amplas sem precisar adicionar cada uma.
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();
}
}
Versão 2.x
Na versão 2.x do SDK, você usa a classe para controlar a LogCategoryFilter
filtragem. O LogCategoryFilter
tem uma propriedade Default
com um valor inicial de Information
, o que significa que as mensagens nos níveis Information
, Warning
, Error
ou Critical
são registadas, mas as mensagens nos níveis Debug
ou Trace
são filtradas.
Tal como na LogCategories
versão 3.x, a CategoryLevels
propriedade permite especificar níveis de log para categorias específicas para que você possa ajustar a saída de log. Se nenhuma correspondência for encontrada no CategoryLevels
dicionário, o filtro retornará ao Default
valor ao determinar se a mensagem deve ser filtrada.
O exemplo a seguir constrói um filtro que, por padrão, filtra todos os logs no Warning
nível. As categorias Function
e Host.Results
são filtradas ao nível Error
. O LogCategoryFilter
compara a categoria atual com todos os inscritos CategoryLevels
e escolhe a partida mais longa. Assim, o nível registado para Debug
corresponder a Host.Triggers
ou Host.Triggers.Queue
. Você pode controlar categorias mais amplas sem precisar adicionar cada uma.
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);
Telemetria personalizada para o Application Insights
O processo de implementação da telemetria personalizada para o Application Insights depende da versão do SDK. Para saber como configurar o Application Insights, consulte Adicionar registos do Application Insights.
Versão 3.x
Porque a versão 3.x do SDK WebJobs depende do host genérico .NET Core, uma fábrica de telemetria personalizada não é mais fornecida. Mas você pode adicionar telemetria personalizada ao pipeline usando a injeção de dependência. Os exemplos nesta seção exigem as seguintes using
instruções:
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Channel;
Você pode usar a seguinte implementação personalizada de ITelemetryInitializer
para adicionar sua própria ITelemetry
instância ao padrão TelemetryConfiguration
.
internal class CustomTelemetryInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
// Do something with telemetry.
}
}
Chame ConfigureServices
no construtor para adicionar uma instância ITelemetryInitializer
personalizada ao pipeline.
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 code 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();
}
}
Quando TelemetryConfiguration
é construído, todos os tipos registrados de ITelemetryInitializer
são incluídos. Para obter mais informações, consulte API do Application Insights para eventos e métricas personalizados.
Na versão 3.x, não tens de esvaziar TelemetryClient
quando o host parar. O sistema de injeção de dependência do .NET Core descarta automaticamente a instância registrada ApplicationInsightsLoggerProvider
, que limpa o TelemetryClient
.
Versão 2.x
Na versão 2.x, a instância TelemetryClient
criada internamente pelo fornecedor do Application Insights para o SDK do WebJobs utiliza ServerTelemetryChannel
. Quando o ponto de extremidade do Application Insights não está disponível ou está a limitar as solicitações de entrada, este canal salva as solicitações no sistema de ficheiros da aplicação web e as reenvia posteriormente.
TelemetryClient
é criado por uma classe que implementa ITelemetryClientFactory
. Por padrão, essa classe é DefaultTelemetryClientFactory
.
Se quiser modificar qualquer parte do pipeline do Application Insights, você pode fornecer sua própria instância do ITelemetryClientFactory
. Em seguida, o host usa a sua classe para construir TelemetryClient
. Por exemplo, esse código substitui DefaultTelemetryClientFactory
para modificar uma propriedade de 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;
}
}
O SamplingPercentageEstimatorSettings
objeto configura a amostragem adaptável. Nesse cenário, em determinados cenários de alto volume, o Applications Insights envia um subconjunto selecionado de dados de telemetria para o servidor.
Depois de criar a fábrica de telemetria, você a passa para o provedor de log do Application Insights:
var clientFactory = new CustomTelemetryClientFactory(instrumentationKey, filter.Filter);
config.LoggerFactory = new LoggerFactory()
.AddApplicationInsights(clientFactory);
Conteúdo relacionado
Este artigo fornece trechos de código que mostram como lidar com cenários comuns para trabalhar com o SDK WebJobs. Para obter exemplos completos, consulte azure-webjobs-sdk-samples.