У меня есть массив веб-сайтов, которые (асинхронно) отправляют аналитику событий на веб-сайт ASP.NET, который затем должен отправлять события в экземпляр Azure EventHubs.
Проблема, с которой я столкнулся, заключается в том, что при запросах, превышающих 50000 в секунду, я заметил, что время моего ответа для обслуживания этих запросов находится в многосекундном диапазоне, что влияет на общее время загрузки для исходного отправляющего веб-сайта. Я увеличил масштаб всех частей, однако я понимаю, что отправка события по запросу не очень эффективна из-за накладных расходов на открытие соединения AMQP с концентраторами событий и отправку полезной нагрузки.
В качестве решения я пытался пакетировать данные событий, которые отправляются в мой экземпляр EventHubs, однако у меня возникли некоторые проблемы с синхронизацией. С каждым запросом я добавляю данные о событиях в статический EventDataBatch
, созданный с помощью EventHubClient.CreateBatch()
с помощью eventHubData.TryAdd()
, затем проверяю, находится ли количество событий в пределах предопределенного порога, и если да, я отправляю события асинхронно через EventHubClient.SendAsync()
. Проблема состоит в том, что, поскольку это приложение ASP .NET, может быть много потоков, пытающихся обслуживать запросы в любом данном экземпляре - любой из которых может пытаться выполнить eventHubData.TryAdd()
или EventHubClient.SendAsync()
в один и тот же момент времени. плохая попытка решить эту проблему. Я попытался вызвать lock(batch)
до eventHubData.TryAdd()
, однако это не решает проблему, поскольку я не могу также заблокировать асинхронный метод EventHubClient.SendAsync()
.
Как лучше всего реализовать это решение, чтобы каждый запрос не требовал собственного запроса к концентраторам событий и мог использовать преимущества пакетной обработки, сохраняя при этом целостность самого пакета и не сталкиваясь с какими-либо проблемами взаимоблокировки?