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


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


the four send中没有任何有关线程安全的附加文档。
methods我最希望线程安全。如果我认为send方法不是线程安全的,那么每次希望发送到消息时,我都会创建一个新的EventHubClient实例。由于底层的tcp连接被重用,除非采取了步骤,否则这可能不会有太多的开销。尽管apparently也存在类似的问题,但是考虑到存在一种创建异步方法的问题,它们很可能拥有自己的AMQP连接。

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

对于任何Azure员工,都可以在文档中对此进行澄清吗?在partitioned senders Azure Table中也出现这种文档问题(假设似乎很可能是错误的),并且通常在MSDN文档中很常见。关于EventHub,这与affectKafka AWS的明确线程安全性声明相反,至少没有明确地将所有内容标记为不安全。我在SDK的开源部分中未找到EventHub,因此无法检查自己。

最佳答案

TLDR:


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



故事

ServiceBus SDK公开了两种创建发送方的模式:


基本的
高级


对于Basic版本-开发人员将直接使用EventHubClient.CreateFromConnectionString() API,而不必担心管理MessagingFactory对象(连接gu's)。只要MessagingFactory相同(所有键和值的字面匹配),SDK就会在所有EventHubClient实例中处理重用connection string的情况,以实现重用。

对于需要在连接级别上有更多控制权的高级开发人员,SB SDK提供了MessagingFactory.CreateFromConnectionString(),并且该开发人员可以创建EventHubClient实例。

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

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

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

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

10-05 19:24