Azure .NET SDK的EventHubClient实例方法是线程安全的吗?

cac*_*sar 4 azure azure-sdk-.net azure-eventhub

我正在编写代码,使用EventHubClient将消息从多个线程发布到C#中的Azure事件中心.EventHubClient的文档包含相当标准的样板.

"此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的.任何实例成员都不保证是线程安全的."

在我最期望的线程安全 四种 发送 方法中,没有关于线程安全的其他文档.我是否相信发送方法不是线程安全的,那么每次我希望发送消息时,我最终都会创建一个新的EventHubClient实例.由于除非采取了步骤,否则显然会重用底层tcp连接,这可能不会产生太多开销.分区发件人也会出现类似的问题,但是如果有一个异步方法来创建一个,他们可能会有自己的AMQP连接.

尽管有文档,EventHubClient线程的一些(如果不是全部)实例方法是否安全?

对于任何Azure人员,是否可以在文档中澄清这一点?这种文档问题(假设它看起来很可能)似乎也会影响 Azure Table,并且通常在MSDN文档中很常见.关于EventHub,这与KafkaAWS Kinesis的明确的线程安全声明相反,至少没有明确地将所有内容标记为不安全.我没有在SDK的开源部分找到EventHubs,所以无法检查自己.

Sre*_*ati 6

TLDR:

  1. .NET SDK中的所有关键运行时操作(也称为数据平面)都是线程安全的.
  2. 创建EventHubClient一次对象并重复使用

故事

ServiceBus SDK公开了两种模式来创建发件人:

  1. 基本
  2. 高级

对于Basic版本 - 开发人员将直接使用EventHubClient.CreateFromConnectionString()API,而不用担心管理MessagingFactory对象(连接gu).SDK将处理重用MessagingFactory所有EventHubClient实例,只要connection string相同 - 所有键和值的文字匹配 - 在SDK中完成此重用.

对于需要在连接级别进行更多控制的高级开发人员,SB SDK提供MessagingFactory.CreateFromConnectionString()并且可以从此开发人员创建EventHubClient实例.

EventHubClient发送到EventHubs的所有实例方法都是严格的线程安全的.通常,所有数据平面操作都是......但是,在从EventHubs读取时,API已针对此模式进行了优化. while(true) { var events = eventHubPartitionReceiver.receive(100); processMyEvents(events); } 因此,对于ex:EventHubReceiver.RuntimeInformation在每次receive调用之后填充没有任何同步的属性.因此,即使实际的receiveAPI是线程安全的 - 随后对RuntimeInformation的调用也不是 - 因为很少有人receive在一个实例上停放多个调用PartitionReceiver.

EventHubClient在每个组件中创建新实例以开始发送消息是默认模式 - ServiceBus SDK将负责重用基础MessagingFactory - 它重用相同的物理套接字(如果连接字符串相同).

如果您正在寻找真正的高吞吐量方案,那么您应该设计一个策略来创建多个MessagingFactory对象,然后分别创建一个EventHubClient.但是 - 在尝试此操作之前,请确保已经增加了Portal上EventHub的Thruput单位,因为默认值仅为1 MBPS - 所有16个分区的累计.

此外,如果您使用的发送模式是分区发件人 - 如果您从同一个eventHubClient(.CreatePartitionedSender())实例创建所有发件人,则他们也将使用相同的基础MessagingFactory .