Файлы загружаются дважды из хранилища Azure. Возможна проблема с удалением? - PullRequest
0 голосов
/ 27 мая 2019

Это проблема, связанная с хранилищем Azure и функциями Azure в Microsoft Azure.

У меня есть контейнер внутри хранилища, а также функция таймера. Идея состоит в том, что всякий раз, когда кто-то помещает zip-файлы (содержащие файлы JSON) в контейнер, функция таймера загружает содержимое в базу данных. Функция таймера постоянно проверяет хранилище, содержит ли оно какие-либо zip-файлы. Причина, по которой я выбираю функцию таймера вместо триггера большого двоичного объекта, заключается в том, что база данных не может обрабатывать слишком много запросов одновременно, если кто-то из контейнеров получит большое количество zip-файлов.

Теперь проблема в том, что иногда функция загружает один и тот же файл дважды в базу данных, даже если я удаляю файл в хранилище после его загрузки. Я понятия не имею, почему, потому что мне кажется, что файлы удалялись успешно каждый раз, когда я проверял это.

До сих пор я тестировал загрузку локальных файлов из консольного приложения, которое отлично работает, так что нет ничего плохого в самой загрузке. Я протестировал запуск метода после Я загрузил все почтовые индексы в хранилище. Это тоже отлично работает. Кажется, проблема возникает, когда функция таймера работает и читает zip-файлы, а в хранилище добавляется больше zip-файлов.

Функция таймера:

static ConcurrentQueue<CloudBlockBlob> queue;

[FunctionName("RezippedUploadFunction")]
public static async System.Threading.Tasks.Task RunAsync([TimerTrigger("0 * * * * *")]TimerInfo myTimer, ILogger log)
{
    var storage = new Storage();
    var blobs = await storage.GetCloudBlockBlobsAsync("rezipped");

    if (blobs.Count == 0) return;
    queue = new ConcurrentQueue<CloudBlockBlob>(blobs);
    var ctasks = 30;
    var tasks = new Task[ctasks];

    for (var i = 0; i < ctasks; i++)
    {
        tasks[i] = Task.Factory.StartNew(() => UploadTaskTest());
    }
    Task.WaitAll(tasks);
    blobs.ForEach(x => Task.WaitAll(storage.HardDeleteBlobAsync(x.Name, "rezipped")));

    Thread.Sleep(1000 * 60);
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}

Способ загрузки:

static void UploadTaskTest()
{
    var finish = DateTime.Now.AddMinutes(5);
    var zip = new Zip();
    var storage = new Storage();
    CloudBlockBlob blob;

    while (queue.TryDequeue(out blob))
    {
        var stream = storage.DownloadBlobAsync(blob.Name, "rezipped");
        Task.WaitAll(stream);
        zip.UploadZip(stream.Result);
        //if (DateTime.Now > finish) break;
    }
}

Дополнительные методы:

public async Task HardDeleteBlobAsync(string name, string container)
{
    await GetContainer(container).GetBlockBlobReference(name).DeleteAsync();
}

Ожидаемый результат заключается в том, что каждый файл, загруженный в хранилище, должен быть прочитан и загружен только один раз в базу данных. Фактическим результатом является то, что иногда (это варьируется много, может быть от 1 до 10-100 файлов) файл читается и загружается дважды.

1 Ответ

0 голосов
/ 27 мая 2019

Я считаю, что было запущено более одного экземпляра, а не один экземпляр.Но я не уверен на 100%

Кроме того, вы можете использовать сетку событий для запуска функции Azure.Поскольку Event будет содержать, будет иметь только контекст, который может помочь вам решить, обрабатывать ли файл или игнорировать его, если он больше.Это решение будет оптимальным, а также сократит затраты на запуск функции (вы можете переключиться на потребление, а не на план обслуживания приложения).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...