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