WebJobs SDK облегчает распространенные сценарии распределенной блокировки через его атрибут SingletonAttribute.Вы можете просто применить SingletonAttribute к функции задания, чтобы гарантировать, что все вызовы этой функции будут сериализованы, даже в масштабированных экземплярах.Это полезно, если вашей функции требуется доступ к другим распределенным ресурсам или выполнение других операций, которые не должны / не могут выполняться одновременно.
[Singleton]
public static async Task ProcessImage([BlobTrigger("images")] Stream image)
{
// Process the image
}
Как и в этом примере, только один экземпляр функции ProcessImage будет работать в любой момент времени.Когда функция запускается новым изображением, добавляемым в контейнер изображений, среда выполнения сначала попытается получить блокировку (аренда BLOB-объектов).После получения блокировка удерживается (и возобновляется аренда BLOB-объектов) на время выполнения функции, что исключает запуск других экземпляров.Если другой экземпляр функции запускается во время работы этой функции, он будет ожидать блокировки, периодически опрашивая ее.
Singleton использует Azure Blob Leases под крышками для реализации распределенной блокировки.Все сложности управления арендой BLOB-объектов, обновлением аренды и т. Д. Обрабатываются SDK.
Детали одиночной блокировки также отображаются на панели инструментов WebJobs, включая текущее состояние блокировки для выполняемой функции,а также как долго функция ожидала блокировки, прежде чем ее получить.Эти сведения можно использовать для просмотра и управления конфликтами блокировок.
Сценарии, не связанные с параллелизмом, потребуют использования Singleton.Некоторые триггеры имеют встроенную поддержку управления параллелизмом через свои параметры конфигурации.В таких случаях вам, вероятно, будет более эффективно использовать встроенную поддержку.Вы можете использовать эти настройки, чтобы убедиться, что ваша функция запускается в одном экземпляре.Чтобы гарантировать, что только один экземпляр функции выполняется среди уменьшенных экземпляров, вы также можете применить к функции блокировку Singleton уровня слушателя (например, [Singleton (Mode = SingletonMode.Listener)]).Ручки конфигурации для некоторых из триггеров:
QueueTrigger - Вы можете установить JobHostConfiguration.Queues.BatchSize в 1 ServiceBusTrigger - Вы можете установить ServiceBusConfiguration.MessageOptions.MaxConcururCallsв 1 FileTrigger - Вы можете установить FileProcessor.MaxDegreeOfParallelism в 1 Однако для триггеров, которые по своей природе не поддерживают управление параллелизмом, или если вы хотите сделать более сложную блокировку с помощью областей Singleton (см. ниже), Singleton - этоправильный путь.
Также я бы сказал, что реализуйте ваш CustomQueueProcessorFactory, как показано ниже, используя двойную блокировку: -
if (_instance == null)
{
lock (SyncObject)
{
if (_instance == null)
{
_instance = new CustomQueueProcessor();
}
}
}
return _instance;