Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье описывается, как работать с пакетом SDK для веб-заданий Azure. Чтобы быстро приступить к работе с WebJobs, см. Начало работы с Azure WebJobs SDK.
Версии SDK для WebJobs
Основные различия между версиями 3.x и 2.x WebJobs SDK заключаются в следующем:
- В версии 3.x добавлена поддержка .NET Core.
- В версии 3.x вы устанавливаете расширение привязки хранилища, необходимое пакетом SDK WebJobs. В версии 2.x привязки хранилища включены в пакет SDK.
- Инструментарий, используемый в Visual Studio 2019 для проектов .NET Core (3.x), отличается от инструментов для проектов .NET Framework (2.x). Дополнительные сведения см. в статье Разработка и развертывание веб-заданий с помощью Visual Studio.
Некоторые примеры в этой статье приведены для обеих версий WebJobs 3.x и WebJobs 2.x.
Azure Functions основаны на пакете SDK для веб-заданий:
- Функции Azure версии 2.x используют пакет SDK веб-заданий версии 3.x.
- Функции Azure версии 1.x используют пакет SDK веб-заданий версии 2.x.
Репозитории исходного кода для функций Azure и пакета SDK для веб-заданий используют нумерирование пакета SDK для веб-заданий. Несколько разделов этой статьи содержат ссылки на документацию по Azure Functions.
Для получения дополнительной информации см. Сравнение пакета SDK веб-заданий и функций Azure.
Хост WebJobs
Хост WebJobs — это контейнер выполнения для функций. Хост прослушивает триггеры и вызывает функции. В версии 3.x хост является реализацией IHost
. В версии 2.x используется объект JobHost
. Вам нужно создать экземпляр узла в коде и написать код, чтобы настроить его работу.
Это изменение архитектуры является ключевым различием между использованием пакета SDK веб-заданий напрямую и его косвенной использованием через Функции Azure. В Функциях Azure служба управляет узлом. Невозможно настроить хост, написав код. В Azure Functions вы настраиваете поведение хоста с помощью параметров в файле host.json
. Эти параметры представляют собой строки, а не код, что ограничивает диапазон их применения для настройки.
Подключения хоста
Пакет SDK WebJobs ищет подключения к службам Azure Storage и Azure Service Bus в файле local.settings.json
, когда вы запускаете локально или в среде WebJob при выполнении в Azure. По умолчанию SDK WebJobs требует подключения к хранилищу с именем AzureWebJobsStorage
.
Когда имя подключения разрешается в одно точное значение, среда выполнения определяет значение как строку подключения, которая обычно включает секрет. Сведения о строках подключения зависят от той службы, к которой вы подключаетесь. Однако имя подключения также может ссылаться на коллекцию нескольких элементов конфигурации. Этот метод полезен для настройки подключений на основе удостоверений личности. Переменные среды можно рассматривать как коллекцию с помощью общего префикса, который заканчивается двойными подчеркиваниями (__
). Затем можно ссылаться на группу, задав имя подключения этому префиксу.
Например, свойство connection
для определения триггера хранилища объектов BLOB Azure может быть Storage1
. Если не настроено ни одно строковое значение переменной среды с именем Storage1
, можно использовать переменную среды с именем Storage1__blobServiceUri
для передачи свойства подключения blobServiceUri
. Свойства подключения у всех служб различны. Сведения о компоненте, использующем подключение, см. в документации.
Подключения на основе идентичности
Чтобы использовать подключения на основе удостоверений в WebJobs SDK, убедитесь, что в проекте используются последние версии пакетов WebJobs. Кроме того, убедитесь, что у вас есть ссылка на Microsoft.Azure.WebJobs.Host.Storage.
В следующем примере показано, как выглядит файл проекта после выполнения этих обновлений:
<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>
При настройке WebJobs в экземпляре HostBuilder убедитесь, что вы осуществили вызов AddAzureStorageCoreServices
. Этот вызов позволяет AzureWebJobsStorage
и другим триггерам и привязкам хранилища использовать идентификацию.
Ниже приведен пример:
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
// Other configurations...
});
Затем можно настроить AzureWebJobsStorage
подключение, задав переменные среды (или параметры приложения при размещении кода в службе приложений Azure):
Переменная среды | Описание | Пример значения |
---|---|---|
AzureWebJobsStorage__blobServiceUri |
URI уровня данных службы BLOB-хранилища учетной записи хранения. Он использует схему HTTPS. | <https://storage_account_name.blob.core.windows.net> |
AzureWebJobsStorage__queueServiceUri |
URI плоскости данных службы очереди учетной записи хранилища. Он использует схему HTTPS. | <https://storage_account_name.queue.core.windows.net> |
Если вы предоставляете конфигурацию любым способом, кроме переменных среды, например в appsettings.json
файле конфигурации, вместо этого необходимо предоставить структурированную конфигурацию для подключения и его свойств:
{
"AzureWebJobsStorage": {
"blobServiceUri": "https://<storage_account_name>.blob.core.windows.net",
"queueServiceUri": "https://<storage_account_name>.queue.core.windows.net"
}
}
Если вы не планируете использовать триггеры BLOB, можно опустить свойство queueServiceUri
.
При локальном запуске кода по умолчанию используется удостоверение разработчика, как описано для DefaultAzureCredential
.
При размещении кода в Службе приложений конфигурация в предыдущем примере по умолчанию использует управляемое удостоверение, назначаемое системой для ресурса. Чтобы вместо этого использовать назначаемое пользователем удостоверение , назначенное приложению, необходимо добавить свойства для подключения, чтобы указать, какое удостоверение следует использовать. Свойство credential
(AzureWebJobsStorage__credential
в качестве переменной среды) должно быть установлено на строку managedidentity
. Свойство clientId
(AzureWebJobsStorage__clientId
как переменная среды) должно быть установлено в идентификатор клиента управляемого удостоверения, назначенного пользователем.
В качестве структурированной конфигурации полный объект будет похож на этот пример:
{
"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>"
}
}
Удостоверение, используемое для AzureWebJobsStorage
, должно иметь назначения ролей, которые предоставляют ему роли владельца данных BLOB-объектов хранилища, участника данных очереди хранилища и участника учетной записи хранилища. Если вы не планируете использовать триггеры BLOB-объектов, можно опустить роли Storage Queue Data Contributor и Storage Account Contributor.
В следующей таблице показаны встроенные роли, которые рекомендуется использовать при работе с триггерами в привязках в стандартной работе. Приложению может потребоваться больше разрешений в зависимости от написанного кода.
Привязка | Примеры встроенных ролей |
---|---|
Триггер BLOB |
Владелец данных блобов хранилищаиучастник данных очереди хранилища См. также предыдущие требования для AzureWebJobsStorage . |
Большой двоичный объект (входные данные) | читатель данных blob-хранилища. |
Blob (выходные данные) | Владелец данных BLOB-объектов хранилища |
Триггер очереди | Читатель данных очереди хранилища, Обработчик сообщений данных в очереди хранилища |
Очередь (выход) | Участник, работающий с данными очереди хранилища, Отправитель данных в очередь хранилища |
триггерслужебная шина 1 | Получатель данных Служебной шины Azure, Владелец данных служебной шины Azure |
Service Bus (выход) | Отправитель данных Служебной шины Azure |
1 Для запуска из тем служебной шины назначение роли должно иметь эффективную область контроля над ресурсом подписки служебной шины. Если включена только тема, возникает ошибка. Некоторые клиенты, такие как портал Azure, не предоставляют ресурс подписки служебной шины в качестве области назначения ролей. В этих сценариях вместо этого можно использовать Azure CLI. Для получения дополнительной информации см. встроенные роли Azure для служебной шины Azure.
Строки подключения в версии 2. x
Версия 2. X пакета SDK не требует определенного имени для строк подключения. В версии 2.x, вы можете использовать собственные имена для этих строк подключения и хранить их в другом месте. Имена можно задать в коде с помощью JobHostConfiguration
, как в примере:
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();
}
Примечание.
Поскольку версия 3.x использует API конфигурации .NET Core по умолчанию, не существует API для изменения имен строк подключения. Дополнительные сведения см. в статье «Разработка и развертывание веб-задач с помощью Visual Studio».
Настройки разработки хоста
Вы можете запустить хост в режиме разработки, чтобы повысить эффективность локальной разработки. Ниже приведены некоторые параметры, которые автоматически изменяются в режиме разработки.
Свойство | Настройка разработки |
---|---|
Tracing.ConsoleLevel |
TraceLevel.Verbose — чтобы максимизировать лог-вывод. |
Queues.MaxPollingInterval |
Низкое значение, чтобы гарантировать немедленную активацию методов очереди. |
Singleton.ListenerLockPeriod |
15 секунд, чтобы помочь в быстрой итеративной разработке. |
Способ включения режима разработки зависит от версии пакета SDK.
Версия 3.x
В версии 3. x, вы используете стандартные API ASP.NET Core для изменения среды узла. Вызовите метод UseEnvironment
в экземпляре HostBuilder
. Передайте строку с именем development
, как показано в следующем примере.
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();
}
}
Версия 2.x
В классе JobHostConfiguration
имеется метод UseDevelopmentSettings
, который включает режим разработки. В следующем примере показано, как использовать параметры разработки. Чтобы config.IsDevelopment
возвращал true
при запуске локально, задайте локальную переменную среды с именем AzureWebJobsEnv
, значение которой будет равно Development
.
static void Main()
{
config = new JobHostConfiguration();
if (config.IsDevelopment)
{
config.UseDevelopmentSettings();
}
var host = new JobHost(config);
host.RunAndBlock();
}
Управление параллельными подключениями (версия 2).x)
В версии 3.x ограничение числа подключений сбрасывается к значению по умолчанию (бесконечное число подключений). Если по какой-либо причине необходимо изменить это ограничение, вы можете использовать свойство MaxConnectionsPerServer
класса WinHttpHandler
.
В версии 2. x, вы управляете числом одновременных подключений к узлу с помощью ServicePointManager.DefaultConnectionLimit
свойства. В 2.x, следует увеличить это значение по умолчанию 2
перед запуском хостинга веб-заданий.
Все исходящие HTTP-запросы, выполняемые из функции, используя HttpClient
, проходят через ServicePointManager
. Когда достигается значение, установленное в DefaultConnectionLimit
, ServicePointManager
начинает добавлять запросы в очередь перед их отправкой. Предположим, что для DefaultConnectionLimit
задано значение 2
, и ваш код выполняет 1000 HTTP-запросов. Изначально только 2 запроса допускаются в ОС. Остальные 998 запросов помещаются в очередь, пока не будет места для них. Время ожидания вашего HttpClient
может истечь, поскольку кажется, что он сделал запрос, но запрос так и не был отправлен операционной системой (ОС) на целевой сервер. Возможно, вы видите поведение, которое не имеет смысла: локальному HttpClient
требуется 10 секунд на завершение запроса, в то время как ваша служба возвращает каждый запрос за 200 мс.
Значение по умолчанию для приложений ASP.NET равно #B0, и это, скорее всего, хорошо подходит для веб-заданий, работающих в плане службы приложений "Базовый" или "Выше". Для веб-заданий обычно требуется параметр AlwaysOn , который поддерживается только планами службы приложений "Базовый" и "Более высокий".
Если ваше веб-задание работает в бесплатном или общем плане App Service, ваше приложение ограничено песочницей службы приложений, которая в настоящее время имеет ограничение на количество подключений, равное 600. Если у вас отсутствует ограничение на количество подключений в ServicePointManager
, скорее всего, будет достигнут порог подключения песочницы, и сайт будет отключен. В этом случае установка DefaultConnectionLimit
на более низкое значение, например 200, может препятствовать этому сценарию и по-прежнему разрешать достаточную пропускную способность.
Параметр нужно настроить перед выполнением HTTP-запросов. По этой причине хост WebJobs не должен автоматически изменять этот параметр. Перед запуском узла могут возникать HTTP-запросы, которые могут привести к неожиданному поведению. Лучше всего задать значение непосредственно в вашем Main
методе перед тем, как инициализировать JobHost
, как показано в этом примере:
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();
}
Триггеры
Пакет SDK для веб-заданий поддерживает тот же набор триггеров и привязок, которые использует Azure Functions. В пакете SDK для веб-заданий триггеры зависят от функций и не связаны с типом развертывания веб-заданий. Веб-задания с функциями, запускаемыми событиями и созданными с помощью пакета SDK, всегда должны публиковаться в виде непрерывного веб-задания с включённой функцией Always On.
Функции должны быть общедоступными методами, и они должны иметь один атрибут триггера или атрибут NoAutomaticTrigger
.
Автоматические триггеры
Автоматические триггеры вызывают функцию в ответ на событие. Рассмотрим этот пример функции, которая активируется сообщением, добавленным в хранилище очередей Azure. Функция возвращает результат, считывая объект Blob из хранилища объектов Blob.
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");
}
Например, атрибут QueueTrigger
вызывает в среде выполнения функцию всякий раз, когда в очереди myqueue-items
появляется очередное сообщение. Атрибут Blob
сообщает среде выполнения использовать сообщение очереди для чтения блоба в контейнере sample-workitems
. Имя элемента BLOB-объекта в контейнере samples-workitems
получено непосредственно от триггера очереди как выражение привязки ({queueTrigger}
).
Примечание.
Время ожидания веб-приложения может истечь через 20 минут бездействия, и только запросы к реальному веб-приложению могут сбросить таймер. Просмотр конфигурации приложения на портале Azure или запросы на сайт расширенных средств не сбрасывают таймер. Если вы настраиваете веб-приложение, которое выполняет задание непрерывно, по расписанию или с использованием триггеров, основанных на событиях, включите настройку Always on в разделе Конфигурация вашего веб-приложения в Azure. Параметр Always on помогает убедиться, что эти типы WebJobs выполняются надежно. Эта функция доступна только в ценовых категориях "Базовый", "Стандартный" и "Премиум".
Ручные триггеры
Чтобы активировать функцию вручную, используйте атрибут NoAutomaticTrigger
.
[NoAutomaticTrigger]
public static void CreateQueueMessage(
ILogger logger,
string value,
[Queue("outputqueue")] out string message)
{
message = value;
logger.LogInformation("Creating queue message: ", message);
}
Процесс запуска функции вручную зависит от версии пакета SDK.
Версия 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();
}
}
Версия 2.x
static void Main(string[] args)
{
JobHost host = new JobHost();
host.Call(typeof(Program).GetMethod("CreateQueueMessage"), new { value = "Hello world!" });
}
Входные и выходные привязки
Входные привязки предоставляют декларативный способ получения данных из служб Azure или сторонних сервисов для вашего кода. Выходные привязки обеспечивают способ обновления данных. В статье Начало работы показан пример каждого из них.
Возвращаемое значение метода можно использовать для привязки выходных данных. Для этого примените атрибут к возвращаемому значению метода. См. пример в разделе Использование возвращаемого значения функции Azure.
Типы привязки
Процесс установки и управления типами привязок зависит от того, используете ли вы версию 3.x или 2.x пакета SDK. Вы можете найти пакет для установки для определенного типа привязки в разделе «Пакеты» справочной статьи по этому типу привязки в Azure Functions. Исключением является триггер файлов и привязка (для локальной файловой системы), которая не поддерживает функции Azure.
Версия 3.x
В версии 3.x привязки хранилища включены в пакет Microsoft.Azure.WebJobs.Extensions.Storage
. Вызовите метод расширения AddAzureStorage
в методе 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();
}
}
Чтобы использовать другие типы триггеров и привязок, установите пакет NuGet, который их содержит, и вызовите метод расширения Add<binding>
, реализованный в расширении. Например, если вы хотите использовать привязку Azure Cosmos DB, установите Microsoft.Azure.WebJobs.Extensions.CosmosDB
и вызовите 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();
}
}
Чтобы использовать триггер таймера или привязку файлов, являющиеся частью основных служб, вызовите методы расширения AddTimers
или AddFiles
.
Версия 2.x
В пакет версии 2.xMicrosoft.Azure.WebJobs
включены следующие типы триггеров и привязок.
- Хранилище BLOB-объектов
- Хранилище очередей
- Хранилище таблиц
Чтобы использовать другие типы триггеров и привязок, установите пакет NuGet, который их содержит, и вызовите метод Use<binding>
для объекта JobHostConfiguration
. Например, если вы хотите использовать триггер таймера, установите Microsoft.Azure.WebJobs.Extensions
и вызовите UseTimers
в методе Main
.
static void Main()
{
config = new JobHostConfiguration();
config.UseTimers();
var host = new JobHost(config);
host.RunAndBlock();
}
Чтобы использовать привязку файлов, установите Microsoft.Azure.WebJobs.Extensions
и вызовите UseFiles
.
Контекст выполнения
В Веб-заданиях можно привязывать к экземпляру ExecutionContext
. С помощью этой привязки вы можете получить доступ к ExecutionContext
в качестве параметра в подписи функции. Например, следующий код использует объект контекста для доступа к идентификатору вызова, который вы можете использовать для корреляции всех журналов, созданных данным вызовом функции.
public class Functions
{
public static void ProcessQueueMessage([QueueTrigger("queue")] string message,
ExecutionContext executionContext,
ILogger logger)
{
logger.LogInformation($"{message}\n{executionContext.InvocationId}");
}
}
Процесс привязки к ExecutionContext
зависит от версии SDK.
Версия 3.x
Вызовите метод расширения AddExecutionContextBinding
в методе 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();
}
}
Версия 2.x
Пакет Microsoft.Azure.WebJobs.Extensions
, упомянутый ранее, также предоставляет специальный тип привязки, который вы можете зарегистрировать, вызвав метод UseCore
. Вы можете использовать привязку для определения параметра ExecutionContext
в сигнатуре своей функции:
class Program
{
static void Main()
{
config = new JobHostConfiguration();
config.UseCore();
var host = new JobHost(config);
host.RunAndBlock();
}
}
Конфигурация привязки
Можно настроить поведение некоторых триггеров и привязок. Процесс настройки зависит от версии пакета SDK.
-
Версия 3.x: установите конфигурацию при вызове
Add<Binding>
ConfigureWebJobs
метода. -
Версия 2.x. Настройка конфигурации путем задания свойств в объекте конфигурации, в который передается
JobHost
.
Эти параметры привязки эквивалентны параметрам в файле проекта host.json
в Azure Functions.
Можно настроить следующие привязки.
- Триггер Azure Cosmos DB
- Триггер Центров событий
- Триггер хранилища очередей
- Привязка SendGrid
- Триггер Service Bus
Конфигурация триггера Azure Cosmos DB (версия 3).x)
В этом примере показано, как настраивать триггер 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();
}
}
Для получения дополнительной информации см. связь Azure Cosmos DB.
Конфигурация триггера Центров событий Azure (версия 3).x)
В этом примере показано, как настроить триггер Центров событий.
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();
}
}
Для получения дополнительной информации см. привязка центров событий.
Конфигурация триггера хранилища очередей
Приведенные ниже примеры показывают, как настроить триггер очередей в хранилище.
Версия 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();
}
}
Для получения дополнительной информации см. привязку хранилища очередей.
Версия 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();
}
Для получения дополнительной информации см. host.json
справочник версии 1.x.
Настройка привязки SendGrid (версия 3.x)
В этом примере показано, как настроить привязку выходных данных SendGrid.
static async Task Main()
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddSendGrid(a =>
{
a.FromAddress.Email = "[email protected]";
a.FromAddress.Name = "Azure Functions";
});
});
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
Для получения дополнительной информации см. SendGrid
.
Настройка триггера служебной шины (версия 3.x)
В этом примере показано, как настроить триггер служебной шины.
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();
}
}
Дополнительные сведения см. в Привязке служебной шины.
Конфигурация для других привязок
Некоторые типы триггеров и привязок определяют собственные настраиваемые типы конфигурации. Например, триггер файла можно использовать для указания корневого пути для отслеживания, как показано в следующих примерах.
Версия 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();
}
}
Версия 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();
}
Выражения привязки
В параметрах конструктора атрибутов вы можете использовать выражения, которые представляют значения из разных источников. Например, в следующем коде путь для атрибута BlobTrigger
создает выражение с именем filename
. При использовании для выходной привязки filename
определяется как имя триггерного BLOB.
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}");
// ...
}
Дополнительные сведения о выражениях привязки см. в разделе Выражения привязки и шаблоны в документации по решению "Функции Azure".
Настраиваемые выражения привязки
Иногда требуется указать в коде имя очереди, имя большого двоичного объекта, контейнера или таблицы, а не жестко задавать их. Например, в некоторых случаях в файле конфигурации или в переменной среды необходимо указывать имя очереди для атрибута QueueTrigger
.
Вы можете назначить имя очереди атрибуту, передав пользовательский резольвер имен во время настройки. Заполнители включаются в параметры конструктора атрибутов триггера или привязки, а код сопоставителя предоставляет фактические значения, используемые вместо этих заполнителей. Вы определяете заполнители, окружая их знаками (%
):
public static void WriteLog([QueueTrigger("%logqueue%")] string logMessage)
{
Console.WriteLine(logMessage);
}
В этом коде используется очередь с именем logqueuetest
в тестовой среде и очереди с именем logqueueprod
в рабочей среде. Вместо жестко запрограммированного имени очереди вы указываете имя записи в коллекции appSettings
.
Резолвер по умолчанию вступает в силу, если вы не предоставляете пользовательский резолвер. Стандартное средство получает значения из настроек приложения или переменных среды.
Начиная с .NET Core 3.1, экземпляр, который вы используете, требует пакета NuGet. Для примера требуется следующее using
выражение:
using System.Configuration;
Ваш NameResolver
класс получает имя очереди из параметров приложения.
public class CustomNameResolver : INameResolver
{
public string Resolve(string name)
{
return ConfigurationManager.AppSettings[name].ToString();
}
}
Версия 3.x
Распознаватель настраивается путем добавления зависимостей. Для этих примеров необходим следующий оператор using
:
using Microsoft.Extensions.DependencyInjection;
Сопоставитель добавляется путем вызова метода расширения ConfigureServices
в HostBuilder
, как показано в этом примере:
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();
}
}
Версия 2.x
Передайте ваш класс NameResolver
в объект JobHost
.
static void Main(string[] args)
{
JobHostConfiguration config = new JobHostConfiguration();
config.NameResolver = new CustomNameResolver();
JobHost host = new JobHost(config);
host.RunAndBlock();
}
Функции Azure реализуют INameResolver
, чтобы получить значения из настроек приложения, как показано на примере. Когда вы используете пакет SDK WebJobs напрямую, вы можете разработать собственную реализацию, которая получает значения заполнителя из любого источника по вашему выбору.
Привязка во время выполнения
Если перед использованием атрибута привязки, например Queue
, Blob
или Table
, необходимо выполнить какие-либо действия с функцией, можно использовать интерфейс IBinder
.
В следующем примере берется входное сообщение очереди и создается новое сообщение с тем же содержимым в выходной очереди. Имя очереди вывода определяется кодом в теле функции.
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));
}
Дополнительные сведения см. в разделе Привязка во время выполнения в документации по Функциям Azure.
Информация о привязке
В документации по Azure Functions содержится справочная информация о каждом типе привязки. Указанная информация содержится в каждой статье справки по привязке. (Этот пример основан на очереди хранилища.)
- Пакеты. Пакет, который нужно установить для включения поддержки привязки в проекте WebJobs SDK.
-
Примеры. Примеры кода. Пример библиотеки классов C# применяется к пакету SDK для веб-заданий. Просто опустите атрибут
FunctionName
. - Атрибуты. Атрибуты, используемые для типа привязки.
- Конфигурация. Объяснения свойств атрибута и параметров конструктора.
- Использование. Сведения о том, к каким типам можно применить привязку и как она работает. Например, алгоритм опроса или обработка отравленной очереди.
Примечание.
Привязки HTTP, вебхуков и Event Grid поддерживаются только функциями Azure, а не пакетом SDK для веб-заданий.
Для получения полного списка привязок, поддерживаемых в среде выполнения Функций Azure, см. Поддерживаемые привязки.
Атрибуты: отключение, время ожидания и одноэлементный
Эти атрибуты можно использовать для управления активацией функций, отменой функций и обеспечения выполнения только одного экземпляра функции.
Отключить атрибут
Используйте атрибут Disable
для управления возможностью вызова функции.
В следующем примере, если параметр Disable_TestJob
приложения имеет значение 1
или True
(не относится к конкретному регистру), функция не выполняется. В этом сценарии среда выполнения создает сообщение журнала Функция 'Functions.TestJob' отключена.
[Disable("Disable_TestJob")]
public static void TestJob([QueueTrigger("testqueue2")] string message)
{
Console.WriteLine("Function with Disable attribute executed!");
}
Когда вы изменяете значения параметров приложения на портале Azure, веб-задание перезапускается, чтобы применить новое значение.
Атрибут можно объявить на уровне параметра, метода или класса. Имя параметра также может содержать выражения привязки.
Атрибут Timeout
Атрибут Timeout
требует отмены функции, если она не завершена в течение определенного периода времени. В следующем примере функция будет выполняться в течение одного дня без атрибута Timeout
. Время ожидания приводит к отмене функции через 15 секунд.
Timeout
Если для параметра атрибута throwOnError
задано true
значение, вызов функции завершается за счет выброса исключения SDK для веб-заданий, когда превышен интервал времени ожидания. Значение по умолчанию throwOnError
равно false
. Если используется атрибут #D0, поведение по умолчанию заключается в отмене вызова функции путем задания маркера отмены, позволяя вызову выполняться на неопределенный срок до тех пор, пока код функции не вернет или не выдает исключение.
[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");
}
Атрибут можно применить Timeout
на уровне класса или на уровне метода, и вы можете указать глобальное время ожидания с помощью JobHostConfiguration.FunctionTimeout
. Тайм-ауты уровня класса или метода переопределяют глобальные тайм-ауты.
Атрибут Singleton
Используйте атрибут Singleton
, чтобы обеспечить выполнение только одного экземпляра функции даже при наличии нескольких экземпляров несущего веб-приложения. Атрибут Singleton
использует распределенную блокировку, чтобы обеспечить выполнение только одного экземпляра.
В этом примере только один экземпляр функции ProcessImage
запускается в любой момент времени.
[Singleton]
public static async Task ProcessImage([BlobTrigger("images")] Stream image)
{
// Process the image.
}
SingletonMode.Listener
У некоторых триггеров есть встроенная поддержка для управления параллелизмом:
-
QueueTrigger. Задайте для параметра
JobHostConfiguration.Queues.BatchSize
значение1
. -
ServiceBusTrigger. Задайте для параметра
ServiceBusConfiguration.MessageOptions.MaxConcurrentCalls
значение1
. -
FileTrigger. Задайте для параметра
FileProcessor.MaxDegreeOfParallelism
значение1
.
Вы можете использовать эти настройки, чтобы обеспечить выполнение функции в режиме единственного экземпляра. Чтобы гарантировать, что запущен только один экземпляр функции, если веб-приложение масштабируется до нескольких экземпляров, примените блокировку Singleton на уровне прослушивателя функции ([Singleton(Mode = SingletonMode.Listener)]
). Блокировки прослушивателя инициируются при запуске узла JobHost. Если все три горизонтально масштабированные экземпляры запускаются одновременно, блокировку получает только один из экземпляров, а начинает работу только один слушатель.
Примечание.
Дополнительные сведения о том, как SingletonMode.Function
работает, см. в репозитории SingletonMode GitHub.
Значения области применения
Можно указать выражение или значение области для атрибута Singleton. Выражение или значение гарантирует сериализацию всех выполнений функции в определенной области. Реализация более детализированной блокировки в этом случае может позволить функции работать в некоторой степени параллельно, сериализуя другие вызовы в соответствии с вашими требованиями. Например, в следующем коде выражение области связывается со значением Region
входящего сообщения. Когда очередь содержит три сообщения из регионов "Восток", "Восток" и "Запад", сообщения из региона "Восток" обрабатываются последовательно. Сообщение с регионом "Запад" выполняется параллельно с сообщениями в регионе "Восток".
[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
Область по умолчанию для блокировки - SingletonScope.Function
. Область блокировки (путь аренды BLOB) связана с полным именем функции. Чтобы заблокировать взаимодействие функций, укажите SingletonScope.Host
и используйте имя идентификатора области видимости, одно и то же для всех функций, которые вы не хотите запускать одновременно. В следующем примере одновременно выполняется только один экземпляр AddItem
или RemoveItem
.
[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.
}
Просмотр двоичных объектов с арендой
Пакет SDK веб-заданий использует аренды BLOB-объектов Azure для реализации распределенной блокировки. Объекты аренды, используемые Singleton
, находятся в контейнере azure-webjobs-host
учетной записи хранения AzureWebJobsStorage
по пути "блокировки". Например, путь к объекту аренды для первого примера ProcessImage
, показанного ранее, может быть locks/061851c758f04938a4426aa9ab3869c0/WebJobs.Functions.ProcessImage
. Все пути включают идентификатор JobHost, в данном случае 061851c758f04938a4426aa9ab3869c0.
Асинхронные функции
Информацию о том, как писать асинхронные функции, см. в документации по Azure Functions.
Токены отмены
Информацию о том, как обрабатывать маркеры отмены, см. документацию Azure Functions о токены отмены и корректное завершение работы.
Несколько случаев
Если ваше веб-приложение работает в нескольких экземплярах, на каждом экземпляре запускается непрерывный WebJob, который прослушивает триггеры и вызывает функции. Различные привязки триггера предназначены для эффективного распределения работы между экземплярами, чтобы масштабирование до большего количества экземпляров позволяло обрабатывать большую нагрузку.
Хотя некоторые триггеры могут привести к двойной обработке, триггеры хранилища очередей и объектов BLOB автоматически предотвращают обработку функцией сообщения очереди или объекта BLOB более одного раза. Дополнительные сведения см. в разделе Проектирование с учетом идентичных входных данных в документации по решению "Функции Azure".
Триггер таймера автоматически гарантирует, что запускается только один экземпляр таймера, поэтому вы не получаете больше одного экземпляра функции, запущенного в заданное время.
Если вы хотите убедиться, что выполняется только один экземпляр функции, даже если существует несколько экземпляров хост-приложения, можно использовать атрибут Singleton
.
Фильтры
Фильтры функций (предварительная версия) предоставляют способ настройки конвейера выполнения веб-заданий с помощью собственной логики. Эти фильтры похожи на фильтры ядра ASP.NET. Их можно реализовать как декларативные атрибуты, которые применяются к функциям или классам. Дополнительные сведения см. на странице о фильтрах функции.
Ведение журналов и мониторинг
Рекомендуется использовать платформу ведения журнала, разработанную для ASP.NET. В статье Начало работы показано, как используется эта платформа.
Фильтрация журнала
Каждый журнал, созданный экземпляром ILogger
, имеет связанные значения Category
и Level
. Параметр LogLevel
является перечислением целочисленных значений, которые обозначают относительную важность.
LogLevel | Код |
---|---|
Трассировка | 0 |
Отладка | 1 |
Информация | 2 |
Предупреждение | 3 |
Ошибка | 4 |
Критически важно | 5 |
нет | 6 |
Вы можете независимо отфильтровать каждую категорию по определенному значению LogLevel
. Например, может потребоваться просмотреть все журналы для обработки триггера BLOB, но только Error
и выше для всего остального.
Версия 3.x
Версия 3. X пакета SDK использует фильтрацию, встроенную в .NET Core. Используйте класс LogCategories
для определения категорий для определенных функций, триггеров или пользователей. Класс LogCategories
также определяет фильтры для определенных состояний узла, таких как Startup
и Results
, чтобы можно было тонко настроить выходные данные ведения журнала. Если совпадение не найдено в определенных категориях, фильтр возвращается к Default
значению при определении того, следует ли фильтровать сообщение.
для LogCategories
требуется следующая using
выражение:
using Microsoft.Azure.WebJobs.Logging;
В следующем примере создается фильтр, который по умолчанию фильтрует все журналы на уровне Warning
. Категории Function
или results
(эквивалентные Host.Results
в версии 2.x) фильтруются на уровне Error
. Фильтр сравнивает текущую категорию со всеми зарегистрированными уровнями в экземпляре LogCategories
и выбирает самое длинное совпадение. Таким образом, уровень, зарегистрированный Debug
, для Host.Triggers
соответствует Host.Triggers.Queue
или Host.Triggers.Blob
. Вы можете управлять более широкими категориями без необходимости добавлять каждую из них.
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();
}
}
Версия 2.x
В версии 2.x пакета SDK класс LogCategoryFilter
используется для управления фильтрацией. Фильтр LogCategoryFilter
имеет свойство Default
с начальным значением Information
, что означает, что все сообщения с уровнями Information
, Warning
, Error
или Critical
регистрируются в журнале, а любые сообщения с уровнями Debug
или Trace
отфильтровываются.
Как и LogCategories
в версии 3.x, свойство CategoryLevels
позволяет указать уровни журналов для определенных категорий, чтобы вы могли точно настроить выходные данные журнала. Если совпадение не найдено в CategoryLevels
словаре, фильтр возвращается к Default
значению при определении того, следует ли фильтровать сообщение.
В следующем примере создается фильтр, который по умолчанию фильтрует все журналы на уровне Warning
. Категории Function
или Host.Results
фильтруются на уровне Error
. Фильтр LogCategoryFilter
сравнивает текущую категорию со всеми зарегистрированными элементами CategoryLevels
и выбирает самое длинное совпадение. Таким образом, уровень, зарегистрированный Debug
, для Host.Triggers
соответствует Host.Triggers.Queue
или Host.Triggers.Blob
. Вы можете управлять более широкими категориями без необходимости добавлять каждую из них.
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);
Настраиваемая телеметрия для Application Insights
Процесс реализации пользовательской телеметрии для Application Insights зависит от версии пакета SDK. Чтобы узнать, как настроить Application Insights, ознакомьтесь с разделом Добавление журнала Application Insights.
Версия 3.x
Так как версия 3.x пакета SDK для веб-заданий использует универсальный узел .NET Core, настраиваемая фабрика данных телеметрии больше не предоставляется. Однако вы можете добавить пользовательскую телеметрию в конвейер, используя внедрение зависимостей. Для примеров в этом разделе требуются следующие инструкции using
:
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Channel;
Для добавления собственного экземпляра ITelemetryInitializer
в ITelemetry
по умолчанию можно использовать следующую пользовательскую реализацию TelemetryConfiguration
.
internal class CustomTelemetryInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
// Do something with telemetry.
}
}
Вызовите ConfigureServices
в построителе, чтобы добавить пользовательский экземпляр ITelemetryInitializer
в конвейер.
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();
}
}
При построении TelemetryConfiguration
, включены все зарегистрированные типы ITelemetryInitializer
. Для получения дополнительной информации см. API Application Insights для пользовательских событий и метрик.
В версии 3.x вам не нужно сбрасывать, когда останавливается хост. Система внедрения зависимостей .NET Core автоматически удаляет зарегистрированный экземпляр #D0, который очищает #B1.
Версия 2.x
В версии 2.x экземпляр TelemetryClient
, созданный поставщиком Application Insights для пакета SDK WebJobs, использует ServerTelemetryChannel
. Когда конечная точка Application Insights недоступна или ограничивает входящие запросы, канал сохраняет запросы в файловой системе веб-приложения и впоследствии повторно отправляет их.
TelemetryClient
создается классом, реализующим ITelemetryClientFactory
. По умолчанию этот класс DefaultTelemetryClientFactory
.
Если вы хотите изменить любую часть конвейера Application Insights, вы можете предоставить собственный экземпляр ITelemetryClientFactory
. Затем хост использует ваш класс для создания TelemetryClient
. Например, этот код переопределяет DefaultTelemetryClientFactory
, чтобы изменить свойство 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;
}
}
Объект SamplingPercentageEstimatorSettings
настраивает адаптивную выборку. В этой ситуации в некоторых случаях с высоким объемом данных Application Insights отправляет на сервер выбранное подмножество данных телеметрии.
После создания фабрики данных телеметрии ее нужно передать поставщику ведения журнала Application Insights.
var clientFactory = new CustomTelemetryClientFactory(instrumentationKey, filter.Filter);
config.LoggerFactory = new LoggerFactory()
.AddApplicationInsights(clientFactory);
Связанный контент
В этой статье содержатся фрагменты кода, которые показывают, как обрабатывать распространенные сценарии для работы с пакетом SDK для веб-заданий. Полные примеры см. на странице с примерами azure-webjobs-sdk-samples.