我正在编写代码,该代码将使用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,这与affect和Kafka 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())实例创建所有发件人。