Пакетирование в концентраторы событий из приложения ASP .NET - PullRequest
0 голосов
/ 22 марта 2019

У меня есть массив веб-сайтов, которые (асинхронно) отправляют аналитику событий на веб-сайт 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().

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

1 Ответ

0 голосов
/ 25 марта 2019

Посмотрите исходный код SDK для приложений, чтобы узнать, как они решили эту проблему - вы можете использовать ключевые части этого для достижения того же с концентраторами событий AMQP.

шаблон,

1) Данные буфера. Определите буфер, который вы будете использовать для потоков с максимальным размером. Несколько потоков записывают данные в буфер

https://github.com/Microsoft/ApplicationInsights-dotnet/blob/develop/src/Microsoft.ApplicationInsights/Channel/TelemetryBuffer.cs

2) Подготовить передачу. Вы можете передавать элементы в буфере либо когда буфер заполнен, либо по истечении некоторого интервала, либо в зависимости от того, что произойдет раньше. Возьмите все предметы из буфера для отправки

https://github.com/Microsoft/ApplicationInsights-dotnet/blob/develop/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs

3) Сделай передачу. Отправка всех элементов в виде нескольких точек данных в одном сообщении концентратора событий,

https://github.com/Microsoft/ApplicationInsights-dotnet/blob/develop/src/Microsoft.ApplicationInsights/Channel/Transmission.cs

Это 3 класса, которые объединяются для достижения этой цели, используя HTTP для отправки на конечную точку сбора Application Insights - вы можете увидеть, как образец шаблона можно применять для сбора, объединения и передачи в концентраторы событий.

Вам нужно будет контролировать максимальный размер сообщения, который составляет 256 КБ на сообщение концентратора событий, что вы можете сделать, установив размер буфера телеметрии - это зависит от вашей клиентской логики, чтобы управлять этим.

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