Какие методы экземпляра Azure .NET SDK EventHubClient являются потокобезопасными?
Я пишу код, который будет публиковать сообщения из нескольких потоков в концентратор событий Azure в C#, используя Event HubClient. Документация для Event HubClient содержит довольно стандартную плиту котла.
"Любые открытые статические (Shared в Visual Basic) члены этого типа являются поточно-ориентированными. Любые члены экземпляров не гарантированно поточно-ориентированы".
Никакой дополнительной документации по безопасности потоков не существует ни в одном из четырех методов отправки, которые, как я ожидаю, будут потокобезопасными. Если бы я полагал, что методы отправки не являются поточно-ориентированными, то я бы в конечном итоге создавал новый экземпляр Event HubClient каждый раз, когда хотел отправить сообщение. Поскольку лежащее в основе TCP-соединение, по- видимому, используется повторно, если не предприняты шаги, это может не потребовать слишком много времени. Подобные проблемы возникают с разделенными отправителями, хотя, учитывая, что существует асинхронный метод для их создания, они вполне могут иметь свое собственное AMQP-соединение.
Являются ли некоторые, если не все, методы экземпляра Event HubClient потокобезопасными, несмотря на документацию?
А для каких-нибудь людей из Azure можно было бы прояснить это в документации? Эта проблема с документацией (если предположить, что она неправильная, как кажется вероятной), похоже, также влияет на таблицу Azure и обычно встречается в документах MSDN. Что касается Event Hub, то это в отличие от четкого заявления о безопасности потоков Kafka и AWS Kinesis, по крайней мере, явно не обозначает все как небезопасные. Я не нашел EventHubs в части SDK с открытым исходным кодом, поэтому не мог проверить себя.
1 ответ
TLDR:
- Все критические операции времени выполнения (или плоскость данных) в.NET SDK являются поточно-ориентированными.
- Создайте
EventHubClient
возражать один раз и использовать повторно
История
ServiceBus SDK предоставляет два шаблона для создания отправителей:
- основной
- продвинутый
Для базовой версии - разработчик будет напрямую использовать EventHubClient.CreateFromConnectionString()
API и не беспокоиться об управлении MessagingFactory
объекты (соединение гу). SDK будет обрабатывать повторное использование MessagingFactory
через все EventHubClient
случаи, пока connection string
то же самое - буквальное совпадение всех ключей и значений - выполняется в SDK для повторного использования.
Для продвинутого разработчика, которому потребуется немного больше контроля на уровне соединения, SB SDK предоставляет MessagingFactory.CreateFromConnectionString()
и из этого разработчик может создать EventHubClient
пример.
Все методы экземпляра EventHubClient
- отправлять в EventHubs строго потокобезопасно. В общем, все операции плоскости данных... Однако, при чтении из EventHubs, API оптимизирован для этого шаблона.
while(true) {
var events = eventHubPartitionReceiver.receive(100);
processMyEvents(events);
}
Так, например: свойства, как, EventHubReceiver.RuntimeInformation
- заселяется после каждого receive
звонить без какой-либо синхронизации. Итак, хотя фактический receive
API является поточно-ориентированным - последующий вызов RuntimeInformation - нет, поскольку редко кто-либо может парковать несколько receive
призывает на случай PartitionReceiver
,
Создание нового экземпляра EventHubClient
в каждом компоненте для запуска отправки сообщений используется шаблон по умолчанию - а ServiceBus SDK позаботится о повторном использовании базового MessagingFactory - который использует один и тот же физический сокет (если строка подключения одинакова).
Если вы ищете реальные сценарии с высокой пропускной способностью, то вам следует разработать стратегию для создания нескольких объектов MessagingFactory, а затем создать каждый из них EventHubClient. Тем не менее - убедитесь, что вы уже увеличили единицы Thruput для вашего EventHub на портале, прежде чем пытаться сделать это, поскольку по умолчанию это всего 1 МБ / с - кумулятивно для всех 16 разделов.
Кроме того, если используемый шаблон отправки является Разделенными отправителями - все они также будут использовать один и тот же базовый MessagingFactory - если вы создадите всех Отправителей из одного и того же экземпляра eventHubClient (.CreatePartitionedSender ()).